Mengapa skrip crontab tidak berfungsi?

Sering, crontab skrip tidak dijalankan sesuai jadwal atau seperti yang diharapkan. Ada banyak alasan untuk itu:

  1. notasi crontab salah
  2. masalah perizinan
  3. variabel lingkungan

Wiki komunitas ini bertujuan untuk mengumpulkan alasan utama untuk crontab skrip tidak dieksekusi seperti yang diharapkan. Tulis setiap alasan dalam jawaban terpisah.

Harap sertakan satu alasan per jawaban - detail tentang mengapa itu tidak dieksekusi - dan perbaiki karena satu alasan itu.

Harap tulis hanya masalah khusus cron, misalnya perintah yang dijalankan seperti yang diharapkan dari shell tetapi dijalankan secara keliru oleh cron.

Lingkungan yang berbeda

Cron melewati satu set minimal variabel lingkungan untuk pekerjaan Anda. Untuk melihat perbedaannya, tambahkan pekerjaan dummy seperti ini:

>* * * * * env /tmp/env.keluaran

Tunggu /tmp/env.output yang akan dibuat, kemudian menghapus pekerjaan lagi. Sekarang bandingkan isi /tmp/env.output dengan output dari env jalankan di terminal reguler Anda.

Sebuah Umum "gotcha" di sini adalah PATH variabel lingkungan menjadi berbeda. Mungkin skrip cron Anda menggunakan perintah somecommand ditemukan di /opt/someApp/bin, yang telah Anda tambahkan PATH di /etc/environment? cron mengabaikan PATH dari file itu, jadi runnning somecommand dari skrip Anda akan gagal saat dijalankan dengan cron, tetapi berfungsi saat dijalankan di terminal. Perlu dicatat bahwa variabel dari /etc/environment akan diteruskan ke pekerjaan cron, hanya saja variabel cron tidak secara khusus mengatur dirinya sendiri, seperti PATH.

Untuk menyiasatinya, cukup atur sendiri PATH variabel di bagian atas script. Misalnya.

#!/bin/bashPATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin# rest of script follows

Beberapa lebih suka hanya menggunakan jalur absolut ke semua perintah sebagai gantinya. Saya sarankan untuk tidak melakukannya. Pertimbangkan apa yang terjadi jika Anda ingin menjalankan skrip Anda pada sistem yang berbeda, dan pada sistem itu, perintahnya ada di /opt/someAppv2.2/bin sebagai gantinya. Anda harus melalui seluruh skrip menggantikan /opt/someApp/bin dengan /opt/someAppv2.2/bin alih-alih hanya melakukan pengeditan kecil pada baris pertama skrip.

Anda juga dapat mengatur variabel PATH dalam file crontab, yang akan berlaku untuk semua pekerjaan cron. Misalnya.

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin15 1 * * * backupscript --incremental /home /root

My top gotcha: jika Anda lupa menambahkan baris baru di akhir crontab file. Dengan kata lain, file crontab harus diakhiri dengan baris kosong.

Di bawah ini adalah bagian yang relevan di halaman manual untuk masalah ini (man crontab kemudian lewati sampai akhir):

   Although cron requires that each entry in a crontab end  in  a  newline   character,  neither the crontab command nor the cron daemon will detect   this error. Instead, the crontab will appear to load normally. However,   the  command  will  never  run.  The best choice is to ensure that your   crontab has a blank line at the end.   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

Cron daemon tidak berjalan. Aku benar-benar kacau dengan ini beberapa bulan yang lalu.

Jenis:

pgrep cron 

Jika Anda tidak melihat nomor (yaitu PID utama cron), maka cron tidak berjalan. sudo /etc/init.d/cron start dapat digunakan untuk memulai cron.

EDIT: daripada meminta skrip init melalui / etc / init.d, gunakan serviceutility, misalnya.

sudo service cron start

EDIT: Anda juga bisa menggunakan systemctl di Linux modern, misalnya.

sudo systemctl start cron

Nama file script di cron.d/, cron.daily/, cron.hourly/, dll., tidak boleh mengandung titik (.), jika tidak, run-parts akan melewatkannya.

Lihat run-Bagian(8):

   If neither the --lsbsysinit option nor the --regex option is given then   the names must consist entirely of upper and lower case  letters,  dig‐   its, underscores, and hyphens.   If  the  --lsbsysinit  option  is given, then the names must not end in   .dpkg-old  or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong  to   one  or more of the following namespaces: the LANANA-assigned namespace   (^[a-z0-9]+$);   the   LSB   hierarchical   and   reserved   namespaces   (^_?([a-z0-9_.]+-)+[a-z0-9]+$);  and  the  Debian cron script namespace   (^[a-zA-Z0-9_-]+$).

Jadi, jika Anda memiliki skrip cron backup.sh, analyze-logs.pl di cron.daily/ direktori, Anda sebaiknya menghapus nama ekstensi.

Dalam banyak lingkungan cron mengeksekusi perintah menggunakan sh, sementara banyak orang menganggap itu akan menggunakan bash.

Saran untuk menguji atau memperbaiki ini untuk perintah gagal:

  • Coba jalankan perintah di sh untuk melihat apakah itu berfungsi:

    sh -c "mycommand"
  • Bungkus perintah dalam subkulit bash untuk memastikannya dijalankan di bash:

    bash -c "mybashcommand"
  • Beri tahu cron untuk menjalankan semua perintah di bash dengan mengatur shell di bagian atas crontab Anda:

    SHELL=/bin/bash
  • Jika perintahnya adalah skrip, pastikan skrip berisi shebang:

    #!/bin/bash

Saya memiliki beberapa masalah dengan zona waktu. Cron berjalan dengan zona waktu instalasi baru. Solusinya adalah me-restart cron:

sudo service cron restart

Path absolut harus digunakan untuk skrip:

Misalnya, /bin/grep harus digunakan sebagai pengganti grep:

# m h  dom mon dow   command0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

Alih-alih:

# m h  dom mon dow   command0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

Ini sangat rumit, karena perintah yang sama akan berfungsi saat dijalankan dari shell. Alasannya adalah bahwa cron tidak memiliki yang sama PATH variabel lingkungan sebagai pengguna.

Jika perintah crontab Anda memiliki % simbol di dalamnya, cron mencoba menafsirkannya. Jadi jika Anda menggunakan perintah apapun dengan % di dalamnya (seperti spesifikasi format ke perintah date) Anda harus menghindarinya.

Itu dan gotchas baik lainnya di sini:
http://www.pantz.org/software/cron/croninfo.html

Cron memanggil skrip yang tidak dapat dieksekusi.

Dengan menjalankan chmod +x /path/to/script, skrip menjadi dapat dieksekusi dan ini akan menyelesaikan masalah ini.

Mungkin juga kata sandi pengguna telah kedaluwarsa. Bahkan kata sandi root dapat kedaluwarsa. Anda dapat tail -f /var/log/cron.log dan Anda akan melihat cron gagal dengan kata sandi kedaluwarsa. Anda dapat mengatur kata sandi agar tidak pernah kedaluwarsa dengan melakukan ini: passwd -x -1 <username>

Dalam beberapa sistem (Debian, Ubuntu) logging untuk cron tidak diaktifkan secara default. Di /etc / rsyslog.conf atau /etc / rsyslog.d / 50-default.conf the line:

# cron.*                          /var/log/cron.log

harus diedit (sudo nano /etc/rsyslog.conf) tidak dikomentari ke:

cron.*                          /var/log/cron.log

Setelah itu, Anda perlu me-restart rsyslog melalui

/etc/init.d/rsyslog restart

atau

service rsyslog restart 

Sumber: Aktifkan crontab logging di Debian Linux

Dalam beberapa sistem (Ubuntu) file logging terpisah untuk cron tidak diaktifkan secara default, tetapi log terkait cron muncul di file syslog. Satu dapat menggunakan

cat /var/log/syslog | grep cron -i

untuk melihat pesan terkait cron.

Anda harus menutup ‘crontab-e’ untuk cron untuk mengambil mempengaruhi. Misalnya menggunakan vim saya mengedit file dan menggunakan :w untuk menulisnya tetapi pekerjaan tidak ditambahkan ke cron sampai saya berhenti juga. Jadi saya tidak akan melihat pekerjaan sampai setelah saya`: q ’ juga.

Saya pikir cara terbaik untuk men-debug cron adalah dengan memeriksa syslog dan menemukan masalahnya.

Dalam kasus saya - email itu pergi ke folder SPAM saya, jadi… periksa bahwa sebelum Anda menghabiskan berjam-jam pada debugging :smiley:

Listrik padam

Silakan periksa yang ini cron - Script doesn't run via crontab but works fine standalone - Ask Ubuntu