Skrip yang berguna biasanya perlu berjalan tanpa menunggu kita mengetik perintah: backup tengah malam, pembersihan cache setiap pekan, atau sinkronisasi setiap sepuluh menit. Linux menyediakan dua mekanisme utama untuk menjadwalkan tugas — cron yang sudah berumur puluhan tahun dan systemd timer yang lebih modern. Pada Chapter ini kita akan membedah keduanya, membaca sintaks jadwal, dan menutup satu jebakan klasik: skrip terjadwal yang berjalan dobel.

Cron dan Sintaks Lima Field #

Cron adalah daemon yang memeriksa tabel jadwal terus-menerus setiap menit dan menjalankan perintah yang waktunya tiba. Tabel jadwal milik user disebut crontab dan diedit dengan perintah crontab -e. Setiap baris non-komentar pada crontab berformat:

text
┌───────────── menit (0-59)
│ ┌───────────── jam (0-23)
│ │ ┌───────────── tanggal (1-31)
│ │ │ ┌───────────── bulan (1-12)
│ │ │ │ ┌───────────── hari dalam pekan (0-6, 0=Minggu)
│ │ │ │ │
│ │ │ │ │    perintah yang dijalankan
* * * * *    /home/budi/bin/backup.sh

Lima field pertama menentukan jadwal; sisanya adalah perintah. Asterisk berarti “setiap nilai”, sehingga contoh di atas berarti setiap menit. Kombinasi yang paling sering dipakai dirangkum berikut:

EkspresiArti
30 2 * * *setiap hari pukul 02:30
0 */2 * * *setiap dua jam, pada menit 0
0 3 * * 1-5pukul 03:00, Senin sampai Jumat
0 4 1 * *pukul 04:00 pada tanggal 1 setiap bulan
*/10 * * * *setiap 10 menit

Untuk memastikan kita membaca lima field dengan benar, skrip kecil berikut memilah satu baris jadwal menjadi pasangan nama-nilai menggunakan awk:

bash
printf '30 2 * * * /home/budi/bin/backup.sh\n' > contoh-crontab.txt
awk 'BEGIN { split("menit jam tanggal bulan hari", nama, " ") }
     { for (i = 1; i <= 5; i++) printf "%-8s = %s\n", nama[i], $i
       printf "perintah = %s\n", $6 }' contoh-crontab.txt

Output yang Dihasilkan:

text
menit    = 30
jam      = 2
tanggal  = *
bulan    = *
hari     = *
perintah = /home/budi/bin/backup.sh

Skrip ini memakai array nama yang dibangun split() lalu mencetak field pertama hingga kelima dengan labelnya. Membaca jadwal dengan pola “label = nilai” seperti ini jauh lebih sulit salah daripada menghitung posisi asterisk secara manual.

Direktori cron Sistem #

Di samping crontab per user, sistem menyediakan direktori khusus untuk skrip yang dijadwalkan berdasarkan frekuensi tetap. Skrip yang diletakkan di /etc/cron.daily berjalan sekali sehari (biasanya sekitar pukul 06:25), /etc/cron.weekly sekali sepekan, dan /etc/cron.hourly sekali sejam. Isi direktori tersebut pada sistem nyata terlihat seperti berikut:

bash
ls /etc/cron.daily

Output yang Dihasilkan:

text
apt-compat
dpkg

Pada contoh di atas, dua skrip bawaan paket (apt-compat dan dpkg) ikut berjalan setiap hari untuk pekerjaan pemeliharaan otomatis. Mekanisme ini cocok untuk skrip sederhana tanpa kebutuhan jadwal khusus: cukup letakkan file, pastikan bisa dieksekusi, dan selesai. Daftar direktori lengkapnya (cron.d, cron.hourly, cron.daily, cron.weekly, cron.monthly) bisa dilihat dengan ls /etc/cron* — beberapa di antaranya mungkin kosong tergantung distribusi.

Environment Cron yang Minimal #

Jebakan terbesar cron bukan sintaksnya, melainkan lingkungan eksekusinya. Cron menjalankan perintah dengan environment yang jauh lebih minim daripada sesi shell interaktif: variabel PATH biasanya hanya /usr/bin:/bin, tidak ada HOME yang kaya konfigurasi, dan tidak ada terminal. Skrip yang bergantung pada ~/.bashrc atau lokasi program di /usr/local/bin akan diam-diam gagal padahal berjalan mulus saat diuji manual.

Karena tidak ada terminal, stdout dan stderr skrip tidak ditampilkan di mana pun. Praktik yang baik adalah mengarahkannya ke file log dengan redirection:

text
30 2 * * * /home/budi/bin/backup.sh >> /home/budi/log/backup.log 2>&1

Baris jadwal ini menambahkan semua output (normal maupun error) ke backup.log sehingga kegagalan bisa ditelusuri keesokan harinya.

Mencegah Eksekusi Dobel dengan flock #

Bila jadwal berjalan setiap menit sementara skripnya kadang memakan waktu lebih dari satu menit, cron akan memulai eksekusi kedua saat yang pertama masih berjalan. Solusi standarnya adalah flock, util yang mengunci file dan menolak menjalankan perintah bila kunci sedang dipegang:

bash
cat > tugas.sh << 'EOF'
#!/bin/bash
echo "tugas dimulai"
sleep 2
echo "tugas selesai"
EOF
chmod +x tugas.sh
flock /tmp/latihan.lock ./tugas.sh &
sleep 1
flock -n /tmp/latihan.lock ./tugas.sh && echo "kedua: jalan" || echo "kedua: ditolak, masih dikunci"
wait

Output yang Dihasilkan:

text
tugas dimulai
kedua: ditolak, masih dikunci
tugas selesai

Mari kita telaah blok di atas:

  1. Baris 1-6 (cat > tugas.sh): skrip contoh yang menyimulasikan tugas lambat dua detik.
  2. Baris 8 (flock /tmp/latihan.lock ./tugas.sh &): eksekusi pertama mengunci /tmp/latihan.lock lalu menjalankan skrip di background.
  3. Baris 9 (sleep 1): memberi waktu agar eksekusi pertama masih sibuk ketika percobaan kedua tiba.
  4. Baris 10 (flock -n ...): opsi -n (nonblocking) membuat flock langsung gagal alih-alih menunggu; karena kunci masih dipegang, percobaan kedua ditolak dan cabang || yang mencetak pesan penolakan yang dijalankan.

Dengan pola flock -n ini, baris crontab menjadi tahan dobel: flock -n /tmp/backup.lock /home/budi/bin/backup.sh. Eksekusi yang tiba saat kunci dipegang akan langsung keluar tanpa menumpuk proses.

systemd Timer dan anacron #

Mekanisme modern untuk penjadwalan adalah systemd timer — pasangan unit *.timer dan *.service yang membawa log terstruktur di journald serta opsi seperti Persistent=true untuk mengejar jadwal yang terlewat saat mesin mati. Perbandingan singkatnya:

Aspekcronsystemd timer
Konfigurasisatu baris di crontabdua file unit
Logsesuai redirect manualotomatis di journald
Tertinggal saat matitidak dikejarbisa dikejar dengan Persistent=true
Ketepatanmenitdetik
Cocok untukjadwal sederhana, portabelintegrasi dengan service sistem

Kita akan membedah penulisan unit timer secara menyeluruh pada Section systemd dan Services, termasuk directive OnCalendar dan pemantauannya melalui journalctl. Untuk mesin yang tidak menyala terus-menerus — laptop misalnya — terdapat pula anacron yang menjalankan tugas harian tertunda begitu sistem aktif kembali.

Dengan skrip yang kini tahu jadwal, tidak dobel, dan mencatat log, kita menutup Section Shell dan Scripting. Kumpulan keterampilan ini akan menjadi bahan baku utama pada Section User dan Permissions, tempat kita belajar mengatur siapa yang boleh menjalankan apa.