Panduan

Crontab: contoh jadwal tugas di Linux, sintaksis, dan kesalahan umum

Diperbarui: · Skillaria.Top

Crontab adalah tabel jadwal yang dibaca daemon cron untuk menjalankan perintah. Setiap baris terdiri dari lima kolom waktu (menit, jam, tanggal, bulan, hari dalam minggu) lalu perintahnya, misalnya */5 * * * * /opt/backup.sh menjalankan skrip setiap 5 menit. Tabel diedit dengan crontab -e, dan sebagian besar masalah berasal dari lingkungan cron yang terbatas: tulis path lengkap dan arahkan keluaran ke log.

Cron adalah penjadwal tugas standar di Linux: daemon cron membaca tabel jadwal (crontab) setiap menit dan menjalankan perintah yang sudah waktunya. Dengan cara ini dibuat backup malam hari, pembersihan berkas sementara, pembaruan sertifikat, dan pengiriman laporan. Di bawah ini sintaksisnya, contoh crontab untuk kasus umum, dan pembahasan kesalahan yang membuat tugas "diam-diam" tidak dijalankan.

Cara membuka dan mengedit crontab

Setiap pengguna memiliki tabelnya sendiri. Pengelolaannya dilakukan dengan perintah crontab, bukan dengan mengedit berkas di /var/spool/cron secara langsung:

PerintahFungsi
crontab -emembuka tabel sendiri di editor (saat pertama kali, akan meminta memilih editor)
crontab -lmenampilkan tabel saat ini
crontab -rmenghapus seluruh tabel tanpa konfirmasi
crontab -i -rmenghapus dengan konfirmasi (Debian/Ubuntu, RHEL)
sudo crontab -u alice -emengedit tabel pengguna lain
crontab berkasmengganti tabel dengan isi berkas

Setelah disimpan, crontab -e memeriksa sintaksis dan menulis crontab: installing new crontab. Jika ada kesalahan di baris, Anda akan melihat errors in crontab file, can't install dan diminta mengedit lagi. Daemon tidak perlu di-restart — perubahan langsung dikenali.

Berhati-hatilah dengan -r: huruf e dan r berdekatan di keyboard, dan tidak ada cadangan tabel. Kebiasaan yang baik adalah menyimpan backup:

crontab -l > ~/crontab.bak
# memulihkan
crontab ~/crontab.bak

Sintaksis crontab: lima kolom waktu

Setiap baris tugas terlihat seperti ini:

# ┌───────── menit (0–59)
# │ ┌─────── jam (0–23)
# │ │ ┌───── tanggal (1–31)
# │ │ │ ┌─── bulan (1–12 atau jan–dec)
# │ │ │ │ ┌─ hari dalam minggu (0–7 atau sun–sat; 0 dan 7 — Minggu)
# │ │ │ │ │
  * * * * * perintah

Di setiap kolom bisa dipakai karakter khusus:

KarakterArtiContoh
*nilai apa pun* * * * * — setiap menit
,daftar0 9,18 * * * — pukul 9:00 dan 18:00
-rentang0 9-18 * * * — setiap jam dari 9 sampai 18
/langkah*/15 * * * * — setiap 15 menit

Langkah bisa digabung dengan rentang: 0 8-20/2 * * * — setiap dua jam dari pukul 8 sampai 20 (8, 10, …, 20). Waktu mengikuti zona waktu sistem — periksa dengan timedatectl.

Contoh crontab untuk setiap hari

JadwalBaris crontab
setiap menit* * * * *
setiap 5 menit*/5 * * * *
setiap 30 menit*/30 * * * * atau 0,30 * * * *
setiap jam tepat di awal jam0 * * * *
setiap 6 jam0 */6 * * *
setiap hari pukul 03:000 3 * * *
setiap hari pukul 23:4545 23 * * *
pada hari kerja pukul 9:000 9 * * 1-5
pada akhir pekan pukul 12:000 12 * * 6,0
setiap Senin pukul 08:3030 8 * * 1
tanggal 1 setiap bulan pukul 00:000 0 1 * *
setiap kuartal0 0 1 1,4,7,10 *
setahun sekali, 1 Januari0 0 1 1 *
setiap 10 menit pada jam kerja*/10 9-18 * * 1-5

Baris tugas lengkap terdiri dari jadwal ditambah perintah:

# backup database setiap malam pukul 3:00
0 3 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1

# hapus berkas sementara yang lebih tua dari 7 hari setiap Minggu
0 4 * * 0 /usr/bin/find /tmp/app -type f -mtime +7 -delete

# cek situs setiap 5 menit
*/5 * * * * /usr/bin/curl -fsS https://example.com/health > /dev/null || /usr/local/bin/alert.sh

Alias khusus @reboot, @daily, dan lainnya

Alih-alih lima kolom, bisa ditulis alias singkat:

AliasSetara dengan
@rebootsekali saat daemon cron mulai (setelah sistem boot)
@hourly0 * * * *
@daily / @midnight0 0 * * *
@weekly0 0 * * 0
@monthly0 0 1 * *
@yearly / @annually0 0 1 1 *
@reboot /home/alice/bin/start-tunnel.sh >> /home/alice/tunnel.log 2>&1

Untuk layanan yang harus berjalan terus dan dihidupkan ulang saat jatuh, @reboot adalah solusi yang lemah: lebih baik buat unit systemd dengan Restart=on-failure.

Cara menjalankan tugas setiap N detik

Satuan terkecil cron adalah satu menit. Jika perlu lebih sering, ada dua cara. Pertama, beberapa baris dengan jeda memakai sleep:

* * * * * /opt/check.sh
* * * * * sleep 30; /opt/check.sh

Kedua, dan lebih tepat, timer systemd dengan OnUnitActiveSec=30s. Jika tugas dijalankan lebih sering dari sekali per menit, biasanya itu tugas untuk daemon atau timer, bukan untuk cron.

Crontab sistem: /etc/crontab dan /etc/cron.d

Selain tabel pengguna, ada juga tabel sistem. Formatnya berbeda: di antara waktu dan perintah ada nama pengguna yang menjalankan perintah tersebut.

# /etc/cron.d/certbot-renew
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root certbot renew --quiet

Letak masing-masing:

  • /etc/crontab — tabel sistem utama; di Debian/Ubuntu, direktori di bawah ini dijalankan dari sini.
  • /etc/cron.d/ — berkas tugas terpisah, cocok untuk diletakkan oleh paket atau lewat Ansible.
  • /etc/cron.hourly/, cron.daily/, cron.weekly/, cron.monthly/ — tempat skrip yang bisa dieksekusi tanpa jadwal; dijalankan oleh run-parts (atau anacron).

Jebakan dengan run-parts: di Debian dan Ubuntu, berkas yang namanya mengandung titik dilewati. Skrip backup.sh di /etc/cron.daily/ tidak akan berjalan — beri nama backup. Untuk melihat apa yang akan dijalankan, gunakan run-parts --test /etc/cron.daily.

Berkas di /etc/cron.d/ harus dimiliki root, tidak boleh bisa ditulis oleh grup maupun pengguna lain, dan harus diakhiri dengan baris baru — jika tidak, cron akan mengabaikannya.

Lingkungan cron: PATH, SHELL, dan variabel

Penyebab utama dari keluhan "di terminal jalan, di cron tidak" adalah lingkungannya. Cron menjalankan perintah lewat /bin/sh, tanpa .bashrc dan .profile Anda, dengan PATH yang minimal (biasanya /usr/bin:/bin). Akibatnya docker, node, atau php yang ada di /usr/local/bin bisa saja tidak ditemukan.

Variabel bisa diatur di awal tabel:

SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com
CRON_TZ=Europe/Moscow

0 6 * * * cd /srv/app && ./report.sh
  • MAILTO — ke alamat mana keluaran tugas dikirim; MAILTO="" mematikan pengiriman email.
  • CRON_TZ — zona waktu untuk jadwal (didukung cronie di RHEL/Fedora; di versi cron Debian variabel ini tidak berfungsi).
  • Substitusi seperti $HOME/bin di nilai variabel tidak dilakukan — tulis path secara lengkap.

Pilihan yang paling andal adalah menulis path absolut ke semua program dan berkas dalam tugas, serta menaruh shebang #!/bin/bash di baris pertama skrip.

Di mana melihat log cron

Cron mencatat ke jurnal fakta bahwa tugas dijalankan, tetapi bukan keluarannya:

# Debian/Ubuntu
grep CRON /var/log/syslog
# lewat journald systemd
journalctl -u cron --since today      # Debian/Ubuntu
journalctl -u crond --since today     # RHEL, Fedora, Rocky
# RHEL tanpa journald
tail -f /var/log/cron

Baris saat tugas dimulai kira-kira seperti ini:

Oct 14 03:00:01 web1 CRON[21544]: (root) CMD (/usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1)

Untuk melihat apa yang dicetak tugas dan error apa yang membuatnya gagal, arahkan stdout dan stderr ke berkas: >> /var/log/job.log 2>&1. Tanpa ini, keluaran dikirim sebagai email lewat surat lokal, dan jika agen surat tidak terpasang, keluaran hilang (di log akan muncul No MTA installed, discarding output).

Mengapa cron tidak menjalankan tugas: kesalahan umum

Perintah tidak ditemukan

Gejala: di log tugas ada command not found. Penyebabnya adalah PATH yang terbatas. Solusinya: path lengkap ke program (which docker akan menunjukkannya) atau baris PATH= di awal tabel.

Tanda persen di dalam perintah

Di crontab, karakter % berarti baris baru: semua yang ditulis setelah % pertama diteruskan ke perintah sebagai input standar. Karena itu baris klasik dengan tanggal di nama berkas rusak:

# salah — perintah terpotong pada % pertama
0 2 * * * tar czf /backup/site-$(date +%F).tar.gz /var/www
# benar — di-escape
0 2 * * * tar czf /backup/site-$(date +\%F).tar.gz /var/www

Lebih mudah lagi, pindahkan logika ke skrip, di mana % tidak perlu di-escape.

Skrip tidak bisa dieksekusi atau baris barunya salah

Error Permission denied berarti berkas tidak memiliki bit x: jalankan chmod +x script.sh atau panggil secara eksplisit, /bin/bash /opt/script.sh. Jika skrip dibuat di Windows, baris baru CRLF menimbulkan error aneh /bin/bash^M: bad interpreter — perbaiki dengan sed -i 's/\r$//' script.sh atau dos2unix.

Path relatif dan direktori kerja

Tugas dimulai dari direktori home pengguna. Jika skrip membaca ./config.ini, ia akan mencarinya di ~. Tambahkan cd /srv/app && sebelum perintah, atau gunakan path absolut di dalam skrip.

Tanggal dan hari dalam minggu diisi bersamaan

Jika kedua kolom diisi, cron berjalan ketika salah satu cocok, bukan keduanya. Baris 0 9 13 * 5 akan berjalan pada tanggal 13 dan setiap Jumat, bukan hanya Jumat tanggal 13. Kondisi yang dimaksud diperiksa di dalam perintah:

0 9 13 * * [ "$(date +\%u)" = 5 ] && /opt/friday13.sh

Tugas saling tumpang tindih

Jika backup berjalan lebih lama dari interval, eksekusi berikutnya dimulai di atas yang sebelumnya. Perlindungannya adalah kunci dengan flock:

*/10 * * * * /usr/bin/flock -n /tmp/sync.lock /opt/sync.sh

Dengan flag -n, salinan kedua langsung berhenti jika yang pertama masih berjalan.

Daemon cron tidak berjalan

Periksa dengan systemctl status cron (di RHEL — crond). Di image minimal, misalnya kontainer Docker, daemon cron tidak ada sama sekali — tugas di crontab tidak akan ada yang menjalankan.

Cara men-debug tugas cron

Jalankan perintah di lingkungan yang semirip mungkin dengan cron:

env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME=$HOME /bin/sh -c '/opt/backup.sh'

Jika error muncul di sini, error yang sama akan muncul di cron. Untuk sementara pasang jadwal * * * * *, arahkan keluaran ke berkas, dan pantau dengan tail -f. Untuk memeriksa ekspresi jadwal, kalkulator cron daring bisa membantu, tetapi keputusan akhir tetap ada di log sistem.

Siapa yang boleh memakai cron: cron.allow dan cron.deny

Akses dibatasi oleh berkas /etc/cron.allow dan /etc/cron.deny. Jika cron.allow ada, crontab hanya tersedia bagi pengguna yang tercantum di dalamnya. Jika tidak ada, tetapi ada cron.deny, crontab tersedia bagi semua kecuali yang tercantum. Pengguna yang dilarang akan menerima pesan You (bob) are not allowed to use this program saat menjalankan crontab -e.

Kesimpulan

Crontab adalah baris-baris berisi lima kolom waktu dan perintah: */5 * * * * berarti setiap 5 menit, 0 3 * * * setiap malam, 0 9 * * 1-5 pada hari kerja. Edit tabel lewat crontab -e, gunakan path absolut, escape %, catat keluaran ke log, dan lindungi tugas yang panjang dengan flock. Contoh-contoh crontab ini mencakup sebagian besar tugas server, dan otomatisasi serta penjadwalan dibahas lebih dalam dalam praktik pada kursus Linux.

Pertanyaan umum

Apa bedanya cron dan anacron?

Cron menjalankan tugas pada waktu yang tepat dan melewatkannya jika komputer sedang mati. Anacron memastikan tugas harian, mingguan, dan bulanan tetap dijalankan setelah komputer dinyalakan kembali, sehingga cocok untuk laptop dan desktop.

Mana yang lebih baik: cron atau timer systemd?

Cron lebih sederhana dan tersedia hampir di mana saja. Timer systemd memberi log di journalctl, dependensi, pembatasan sumber daya, dan opsi Persistent=true untuk eksekusi yang terlewat, sehingga di server modern semakin sering dipilih untuk tugas penting.

Di mana crontab pengguna disimpan secara fisik?

Di Debian dan Ubuntu di /var/spool/cron/crontabs/nama, di RHEL dan Fedora di /var/spool/cron/nama. Sebaiknya jangan mengedit berkas ini langsung, gunakan crontab -e.

Bagaimana cara menonaktifkan tugas di crontab sementara?

Beri tanda # di awal baris melalui crontab -e. Untuk menonaktifkan semua tugas pengguna, simpan tabel ke berkas dengan crontab -l, lalu hapus dengan crontab -r.

Bagaimana menjalankan tugas pada hari terakhir setiap bulan?

Tidak ada kolom khusus untuk itu. Jalankan tugas pada tanggal 28–31 dan periksa apakah besok sudah tanggal 1: 0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = 01 ] && /opt/job.sh.

Pelajari topik ini lewat video

Topik ini dibahas mendalam dengan praktik di kursus “Linux: с нуля до уверенного администрирования”.

Ke kursus