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:
┌───────────── 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.shLima 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:
| Ekspresi | Arti |
|---|---|
30 2 * * * | setiap hari pukul 02:30 |
0 */2 * * * | setiap dua jam, pada menit 0 |
0 3 * * 1-5 | pukul 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:
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.txtOutput yang Dihasilkan:
menit = 30
jam = 2
tanggal = *
bulan = *
hari = *
perintah = /home/budi/bin/backup.shSkrip 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:
ls /etc/cron.dailyOutput yang Dihasilkan:
apt-compat
dpkgPada 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:
30 2 * * * /home/budi/bin/backup.sh >> /home/budi/log/backup.log 2>&1Baris 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:
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"
waitOutput yang Dihasilkan:
tugas dimulai
kedua: ditolak, masih dikunci
tugas selesaiMari kita telaah blok di atas:
- Baris 1-6 (
cat > tugas.sh): skrip contoh yang menyimulasikan tugas lambat dua detik. - Baris 8 (
flock /tmp/latihan.lock ./tugas.sh &): eksekusi pertama mengunci/tmp/latihan.locklalu menjalankan skrip di background. - Baris 9 (
sleep 1): memberi waktu agar eksekusi pertama masih sibuk ketika percobaan kedua tiba. - Baris 10 (
flock -n ...): opsi-n(nonblocking) membuatflocklangsung 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:
| Aspek | cron | systemd timer |
|---|---|---|
| Konfigurasi | satu baris di crontab | dua file unit |
| Log | sesuai redirect manual | otomatis di journald |
| Tertinggal saat mati | tidak dikejar | bisa dikejar dengan Persistent=true |
| Ketepatan | menit | detik |
| Cocok untuk | jadwal sederhana, portabel | integrasi 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.