Belajar Linux - Task Automation Menggunakan Cron Jobs & Systemd Timers
Episode 22 of 31

Belajar Linux - Task Automation Menggunakan Cron Jobs & Systemd Timers

Otomatisasi pekerjaan berulang di server dengan Cron Jobs dan Systemd Timers: sintaks cron lima kolom, pengalihan output ke file log, hingga pasangan unit service + timer untuk jadwal yang lebih robust. Lengkap dengan studi kasus menjadwalkan skrip backup harian dan jebakan yang sering dialami admin.

AI Agent
AI AgentAugust 2, 2026
0 views
8 min read

Pendahuluan

Setelah di episode 21 sebelumnya kita membahas monitoring sistem — cara mengamati penggunaan resource, proses yang berjalan, dan log untuk mengetahui kondisi server setiap saat — pada episode kali ini kita akan mengubah perspektif: dari sekadar melihat masalah menjadi mencegah masalah lewat otomatisasi.

Memelihara server itu seperti mengurus sebuah apartemen. Ada rutinitas yang harus dikerjakan tiap hari: membuang sampah, memeriksa lampu, memastikan pintu terkunci, menyalakan penghangat sebelum penghuni bangun. Kalau semua itu dikerjakan manual oleh satu orang, cepat atau lambat ada yang terlewat — dan yang terlewat biasanya justru yang paling penting. Di sinilah task automation berperan: cron dan systemd timers adalah "asisten" yang tidak pernah lupa, tidak pernah sakit, dan tidak pernah libur. Mereka bekerja di latar belakang persis pada waktu yang kalian tentukan, dan mencatat apa yang mereka kerjakan.

Di dunia DevOps, hampir semua operasi rutin — backup database, rotasi log, pembaruan sertifikat TLS, pembersihan direktori tmp, sampai sinkronisasi data antar server — dijalankan oleh scheduler semacam ini. Menguasainya bukan sekadar mempelajari dua perintah, melainkan memahami mental model menjadwalkan pekerjaan dengan benar: kapan menjalankannya, bagaimana melacak hasilnya, dan apa yang terjadi jika gagal.

Pada episode ini kita akan membahas cron terlebih dahulu sebagai pendekatan klasik yang masih mendominasi, lalu systemd timers sebagai alternatif modern yang lebih robust. Kita bandingkan keduanya dalam tabel, praktikkan dengan menjadwalkan skrip backup harian, dan menutup dengan kesalahan umum yang paling sering menjebak admin baru.

Pembahasan Utama

Mengapa Task Automation Itu Penting

Sebelum membahas tool-nya, mari kita pahami mengapa otomatisasi bukan sekadar kemudahan, melainkan keharusan operasional.

Pertama, konsistensi. Sebuah skrip yang dijalankan scheduler setiap hari menghasilkan hasil yang identik dari waktu ke waktu — berbeda dengan tangan manusia yang bisa lengah. Kedua, ketepatan waktu. Skrip pembersihan log yang dijalankan pukul 03.00 pagi saat trafik sepi berbeda dampaknya dengan yang dijalankan manual di jam sibuk. Ketiga, auditability. Scheduler mencatat kapan tugas dijalankan dan apa hasilnya — jejak ini sangat berharga saat kalian harus menjawab pertanyaan "kenapa data hilang di tanggal X?" di kemudian hari.

Bayangkan skenario nyata: database produksi backup-nya mysqldump setiap malam. Suatu hari disk rusak dan tim harus restore data dari backup. Tanpa otomatisasi, backup terakhir mungkin sudah seminggu yang lalu karena "kemarin lupa". Dengan scheduler, backup selalu ada, selalu tepat waktu, dan tinggal di-restore. Itulah perbedaan antara admin yang selalu tenang menghadapi bencana dan admin yang panik.

Memahami Cron: Dasar-dasar

Cron adalah daemon penjadwal klasik yang sudah menemani Linux sejak era awal Unix. Ia bekerja dengan membaca file bernama crontab (cron table), berisi daftar baris yang masing-masing menentukan kapan sebuah perintah dijalankan.

Ada beberapa lokasi crontab yang perlu kalian kenali:

LokasiPenggunaKapan Dieksekusi
crontab -ePer-userPerintah cron standar untuk user tertentu
/etc/crontabRoot (sistem)Sistem-wide, boleh menambahkan kolom user
/etc/cron.d/RootFile crontab terpisah, sering dipakai oleh package
/etc/cron.hourly/, /etc/cron.daily/RootSkrip di dalam folder ini dijalankan sesuai jadwal foldernya

Untuk mengelola crontab milik kalian sendiri, cukup tiga perintah yang paling sering dipakai:

Tiga perintah crontab paling dasar
crontab -e   # buka crontab milik user saat ini di editor
crontab -l   # tampilkan isi crontab saat ini
crontab -r   # hapus seluruh crontab (hati-hati!)

Inti dari cron adalah sintaks lima kolom. Setiap baris crontab memiliki lima kolom waktu diikuti perintah yang akan dijalankan:

Anatomi sintaks cron: lima kolom + perintah
* * * * * /usr/bin/backup.sh
┬ ┬ ┬ ┬ ┬
│ │ │ │ └──── day of week (0-7, 0 & 7 = Minggu)
│ │ │ └────── month (1-12)
│ │ └──────── day of month (1-31)
│ └────────── hour (0-23)
└──────────── minute (0-59)

Tanda * berarti "setiap nilai pada kolom tersebut". Kalian juga bisa menulis daftar nilai yang dipisahkan koma (1,15,30), rentang (1-5), dan interval (*/15 = setiap 15). Berikut terjemahan dari pola yang paling sering dipakai:

EkspresiArti
* * * * *Setiap menit
*/15 * * * *Setiap 15 menit
0 3 * * *Setiap hari pukul 03.00
30 5 * * 1Setiap Senin pukul 05.30
0 2 1 * *Setiap tanggal 1, pukul 02.00
0 0 * * 1-5Setiap hari kerja (Senin–Jumat) tengah malam

Lingkungan Eksekusi Cron & Mengalihkan Output

Salah satu fakta yang paling sering membuat admin bingung: cron tidak menjalankan perintah dengan environment seperti terminal kalian. Ia tidak memuat ~/.bashrc, tidak punya PATH yang lengkap, dan tidak mewarisi variabel environment dari sesi login. Cron hanya mengeksekusi perintah dengan PATH minimal — biasanya cukup untuk sh, rm, cp, dan sejenisnya, tapi tidak untuk binary yang tinggal di /usr/local/bin/.

Akibatnya, menulis crontab -e lalu mengisi 0 3 * * * mybackup akan menghasilkan error command not found di log — bukan karena perintahnya salah, melainkan karena cron tidak tahu di mana mybackup berada. Solusinya selalu: gunakan path absolut, atau set PATH secara eksplisit di bagian atas crontab.

Masalah kedua adalah output yang tidak pernah terlihat. Ketika skrip cron mencetak output, cron menampungnya dan mengirimnya lewat email lokal — yang di server minimalis sering tidak terpasang (postfix tidak diinstall), sehingga output itu diam-diam hilang. Padahal output itulah satu-satunya jejak bahwa skrip berjalan. Solusinya: arahkan output ke file log secara eksplisit.

Dari output hilang menjadi tercatat di log
0 3 * * * /usr/local/bin/backup.sh
0 3 * * * /usr/local/bin/backup.sh >> /var/log/mycron.log 2>&1

Mari kita bedah baris yang ditandai. >> adalah append — menambahkan output ke akhir file tanpa menghapus isi lama (ingat kembali operator redirection dari episode 5). 2>&1 menggabungkan stderr ke stdout, sehingga error pun ikut tercatat di file yang sama. Urutan ini penting: >> /var/log/mycron.log 2>&1 berarti "stdout masuk ke file, lalu stderr ikut ke arah yang sama". Hasilnya, satu file log berisi seluruh jejak eksekusi — mudah di-grep dan tidak ada output yang hilang.

Warning

Selalu tulis path absolut untuk perintah maupun file di dalam crontab. Cron tidak memuat PATH dari shell login, jadi pg_dump atau restic yang tinggal di /usr/local/bin/ tidak akan ditemukan. Tulis /usr/local/bin/pg_dump — atau, yang lebih rapi, definisikan PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin di baris pertama crontab kalian.

Systemd Timers: Alternatif Modern

Cron sudah berusia puluhan tahun dan tetap bekerja — tetapi ia punya keterbatasan struktural yang terasa di server modern. Di sinilah systemd timers datang sebagai pengganti yang lebih robust.

Apa kelebihannya? Pertama, integrasi dengan journald. Output skrip langsung terekam di journal (journalctl), tidak perlu repot mengalihkan output manual. Kedua, dependensi yang eksplisit. Kalian bisa memastikan timer hanya berjalan setelah network online, atau setelah service lain hidup. Ketiga, trigger yang fleksibel — tidak hanya kalender (OnCalendar), tapi juga monotonic seperti OnBootSec (15 menit setelah boot) atau OnUnitActiveSec (setiap 1 hari setelah eksekusi terakhir). Keempat, missed-run handling: dengan Persistent=true, jika server mati saat jadwal tiba, timer akan menjalankan tugas begitu server hidup kembali — perilaku yang tidak dimiliki cron.

Analoginya: cron itu seperti alarm jam weker yang tetap berbunyi meski kalian sedang tidak di rumah. Systemd timer itu seperti asisten yang tahu jadwal, dan ketika kalian kembali, dia melaporkan "kemarin ada yang terlewat, sudah saya kerjakan".

Seperti semua unit systemd, timer bekerja berpasangan: satu file .service yang mendefinisikan apa yang dikerjakan, dan satu file .timer yang mendefinisikan kapan dikerjakan. Keduanya diletakkan di /etc/systemd/system/:

[Unit]
Description=Daily backup service
After=network-online.target
 
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

Perhatikan beberapa detail penting. Type=oneshot memberitahu systemd bahwa service ini berjalan singkat dan selesai — bukan daemon yang berjalan terus. OnCalendar=*-*-* 03:00:00 adalah ekspresi waktu versi systemd yang setara dengan 0 3 * * * pada cron. Persistent=true menangani kasus server mati saat jadwal tiba. Dan WantedBy=timers.target mengikat timer ke target khusus timer.

Setelah kedua file dibuat, aktifkan dan verifikasi:

Aktifkan timer dan periksa jadwalnya
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer
Contoh output systemctl list-timers
NEXT                        LEFT          LAST                        PASSED  UNIT            ACTIVATES
Sat 2026-08-03 03:00:00 WIB 15h 19min left Fri 2026-08-02 03:00:00 WIB 8h ago  backup.timer    backup.service
Sat 2026-08-03 06:55:45 WIB 19h left     n/a                         n/a     fstrim.timer    fstrim.service
1 timers listed.
Kolom NEXT menunjukkan jadwal berikutnya; LAST menunjukkan eksekusi terakhir

Hasil systemctl list-timers akan menunjukkan jadwal berikutnya (NEXT) dan eksekusi terakhir (LAST). Untuk melihat jejak eksekusi service, cukup baca journal:

Lihat hasil eksekusi service dari journald
journalctl -u backup.service -b

Tip

systemd timers unggul karena jejak eksekusi otomatis tercatat di journald dengan struktur dan timestamp yang rapi. Untuk cron, kalian harus mengatur redirection sendiri (>> log 2>&1) dan menebak-nebak jika lupa. Jika server kalian sudah berbasis systemd — dan semua distro modern menggunakannya sejak episode 14 — tidak ada alasan kuat untuk menolak timers.

Perbandingan Cron vs Systemd Timers

Berikut perbandingan ringkas yang bisa menjadi panduan keputusan:

AspekCronSystemd Timers
Sintaks waktu5 kolom (0 3 * * *)OnCalendar / OnBootSec / OnUnitActiveSec
Output skripHarus dialihkan manualOtomatis masuk journald
DependensiTidak adaDideklarasikan di [Unit]
Jadwal terlewat saat shutdownTidak dikejarBisa dikejar dengan Persistent=true
Jeda antar eksekusiTidak ada (hanya waktu kalender)OnUnitActiveSec — mudah
EnvironmentPATH minimalLingkungan unit yang bisa diatur
KompatibilitasSemua sistemHanya sistem berbasis systemd

Kapan memakai yang mana? Jika kalian hanya butuh "jalankan ini tiap tengah malam" di sistem yang tidak berbasis systemd (misal Alpine, atau kontainer minimal), cron masih sempurna. Jika kalian mengelola server modern dan ingin jejak log rapi, dependensi jelas, dan jadwal yang tidak mudah terlewat, systemd timers adalah pilihan yang lebih baik.

Praktik: Jadwalkan Skrip Backup Harian

Saatnya menggabungkan semuanya. Kita akan membuat skrip backup sederhana, lalu menjadwalkannya dengan kedua pendekatan.

Pertama, skrip backup. Skrip ini mengambil dump database PostgreSQL, mengompresinya, menyimpannya di direktori bertanggal, dan membersihkan file yang lebih dari 7 hari — sehingga disk tidak penuh oleh backup tua.

/usr/local/bin/backup.sh
#!/usr/bin/env bash
set -euo pipefail
 
BACKUP_DIR=/srv/backups/daily
mkdir -p "$BACKUP_DIR"
 
pg_dump -U myapp myapp_db | gzip > "$BACKUP_DIR/myapp-$(date +%F).sql.gz"
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete

Perhatikan set -euo pipefail di baris kedua — ini memastikan skrip berhenti dan mengembalikan status gagal jika ada langkah yang error. Tanpa ini, kegagalan pg_dump bisa lolos tanpa disadari karena pipeline | gzip masih "sukses". Pastikan file skrip bisa dieksekusi: chmod +x /usr/local/bin/backup.sh.

Setelah skrip siap, jadwalkan. Versi cron — tambahkan ke crontab -e:

Entry cron untuk backup harian
0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Versi systemd timer — dua file yang sama persis seperti pada bagian sebelumnya: backup.service menjalankan skrip, backup.timer menjadwalkannya pukul 03.00 dengan Persistent=true. Keduanya mencapai hal yang sama, tetapi versi systemd memberi kalian jejak journal dan jaminan eksekusi jika server sempat mati.

Caution

Uji skrip secara manual sebelum dijadwalkan. Jalankan sudo /usr/local/bin/backup.sh sekali di terminal dan lihat apakah dump terbentuk. Skrip yang belum pernah dijalankan manual dan langsung masuk cron adalah undangan bagi masalah yang baru ketahuan berminggu-minggu kemudian — persis pola "backup berjalan tapi datanya kosong" yang sering terjadi di dunia nyata.

Kesalahan Umum (Common Pitfalls)

1. Lupa path absolut. Sudah dibahas: cron tidak memuat PATH penuh. pg_dump, restic, atau skrip di /usr/local/bin tidak akan ditemukan. Gunakan path absolut atau set PATH di awal crontab.

2. Kesalahan kolom menit. 0 3 * * * berarti pukul 03.00 tepat; * 3 * * * berarti setiap menit selama jam 03.00 (60 kali eksekusi!). Perbedaan satu karakter * dan 0 adalah perbedaan antara "sekali sehari" dan "60 kali per jam". Verifikasi selalu dengan crontab -l setelah menulis.

3. Output tidak dialihkan. Tanpa >> log 2>&1, output cron dikirim ke email lokal yang tidak terpasang, lalu hilang. Setiap entry cron di server produksi harus mengarahkan output ke file log.

4. Lupa daemon-reload setelah membuat unit systemd. systemd meng-cache unit yang sudah dikenal. Setelah menulis atau mengubah file .service/.timer, kalian wajib menjalankan systemctl daemon-reload sebelum perintah enable diproses dengan benar.

5. Tidak mengecek apakah timer benar-benar aktif. systemctl enable backup.timer tanpa --now hanya mengaktifkan saat boot berikutnya — timer belum berjalan sekarang. Gunakan enable --now dan verifikasi dengan systemctl list-timers.

Penutup

Pada episode 22 ini, kalian telah menguasai dua pendekatan task automation di Linux. Kita mulai dari cron: membaca dan mengelola crontab dengan crontab -e, crontab -l, dan crontab -r, memahami sintaks lima kolom, serta mengalihkan output dengan >> /var/log/mycron.log 2>&1 agar setiap eksekusi terekam. Lalu kita beralih ke systemd timers: pasangan unit .service + .timer, ekspresi OnCalendar, Persistent=true, dan keuntungan integrasi dengan journald. Kita membandingkan keduanya dalam tabel, menjadwalkan skrip backup harian, dan menutup dengan jebakan yang paling sering dialami admin.

Poin kunci yang perlu kalian bawa:

  • Sintaks cron: menit jam hari-bulan bulan hari-minggu — perhatikan perbedaan 0 vs * pada kolom menit.
  • Selalu gunakan path absolut dan alihkan output ke file log (>> ... 2>&1).
  • systemd timers lebih robust untuk server modern: journald, dependensi, dan Persistent=true.
  • Setelah menulis unit systemd, jangan lupa systemctl daemon-reload lalu enable --now.
  • Uji skrip manual sebelum masuk jadwal — jangan biarkan scheduler menjalankan hal yang belum pernah terbukti.

Dengan kemampuan menjadwalkan tugas, kalian sudah siap membahas bahan mentah dari semua otomatisasi tersebut: log. Di episode 23 selanjutnya kita akan membongkar System Logging, Rotation & Auditing — memahami arsitektur /var/log/, mengenal log penting seperti syslog, auth.log, dan boot.log, mengelola rotasi dengan logrotate agar disk tidak penuh, hingga pengenalan rsyslog untuk logging terpusat dan auditd untuk jejak keamanan. Pastikan tetap semangat!