Sering kali, crontab
script yang tidak dilaksanakan pada jadwal atau seperti yang diharapkan. Ada banyak alasan untuk itu:
Komunitas ini wiki bertujuan untuk agregat atas alasan untuk crontab
script tidak dijalankan seperti yang diharapkan. Menulis alasan masing-masing dalam jawaban yang terpisah.
Harap sertakan salah satu alasan per jawabannya - rincian tentang mengapa hal itu's tidak dieksekusi - dan memperbaiki(es) untuk itu salah satu alasan.
Silakan menulis hanya cron-isu tertentu, misalnya perintah yang melaksanakan seperti yang diharapkan dari shell tapi jalankan keliru oleh cron.
Lingkungan yang berbeda
Cron melewati minimal set variabel lingkungan untuk pekerjaan anda. Untuk melihat perbedaan, menambahkan dummy pekerjaan seperti ini:
* * * * * env > /tmp/env.output
Menunggu /tmp/env.output
yang akan dibuat, kemudian menghapus pekerjaan lagi. Sekarang bandingkan isi /tmp/env.output
dengan output dari amplop
berjalan dalam anda secara teratur terminal.
Umum "gotcha" di sini adalah PATH
variabel lingkungan yang berbeda. Mungkin anda cron script menggunakan perintah somecommand
ditemukan di /opt/someApp/bin
, yang anda've ditambahkan ke JALAN
di /etc/environment
? cron mengabaikan PATH
dari file itu, jadi runnning somecommand
dari naskah anda akan gagal ketika dijalankan dengan cron, tetapi bekerja ketika berjalan di terminal. It's dicatat bahwa variabel-variabel dari /etc/environment
akan diteruskan ke cron jobs, tidak hanya variabel cron khusus set itu sendiri, seperti JALAN
.
Untuk mendapatkan sekitar itu, hanya mengatur anda sendiri PATH
variabel di atas script. E. g.
#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# rest of script follows
Beberapa memilih untuk hanya menggunakan jalan mutlak untuk semua perintah sebagai gantinya. Saya merekomendasikan melawan itu. Pertimbangkan apa yang terjadi jika anda ingin menjalankan skrip pada sistem yang berbeda, dan pada sistem itu, perintah ini di /opt/someAppv2.2/bin
sebagai gantinya. Anda'd memiliki untuk pergi melalui seluruh script menggantikan /opt/someApp/bin
dengan /opt/someAppv2.2/bin
bukan hanya melakukan hal kecil edit pada baris pertama naskah.
Anda juga dapat mengatur variabel PATH di file crontab, yang akan berlaku untuk semua cron jobs. E. g.
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
15 1 * * * backupscript --incremental /home /root
Saya atas gotcha: Jika anda lupa untuk menambahkan baris baru pada akhir crontab
file. Dengan kata lain, file crontab harus berakhir dengan baris kosong.
Di bawah ini adalah bagian yang relevan di halaman man untuk masalah ini (man crontab
kemudian melompat ke 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, maka cron tidak berjalan. sudo /etc/init.d/cron mulai
dapat digunakan untuk menjalankan cron.
EDIT: daripada memohon init script melalui /etc/init.d, gunakan layanan utilitas, misalnya
sudo service cron start
EDIT: Juga anda bisa menggunakan systemctl modern di Linux, misalnya
sudo systemctl start cron
Script file di cron.d/
, cron.harian/
, cron.jam/
, dll., tidak boleh mengandung titik (.
), jika berjalan-bagian yang akan melewatkan mereka.
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 cron script backup.sh
, analyze-logs.pl
di cron.harian/
direktori, anda'a yang terbaik untuk menghapus ekstensi nama.
Di banyak lingkungan cron mengeksekusi perintah-perintah menggunakan sh
, sementara banyak orang menganggap itu akan menggunakan bash
.
Saran untuk menguji atau memperbaiki ini untuk gagal perintah:
sh
untuk melihat apakah ia bekerja:sh -c "mycommand"
bash -c "mybashcommand"
SHELL=/bin/bash
Path absolut harus digunakan untuk script:
Misalnya, /bin/grep
harus digunakan sebagai pengganti dari grep
:
# m h dom mon dow command
0 0 * * * /bin/grep ERROR /home/adam/run.log &> /tmp/errors
Bukannya:
# m h dom mon dow command
0 0 * * * grep ERROR /home/adam/run.log &> /tmp/errors
Hal ini sangat rumit, karena perintah yang sama akan bekerja ketika dieksekusi dari shell. Alasannya adalah bahwa cron
tidak sama PATH
variabel lingkungan sebagai pengguna.
Jika anda perintah crontab memiliki %
simbol di dalamnya, cron mencoba untuk menafsirkannya. Jadi jika anda menggunakan perintah dengan %
di dalamnya (seperti spesifikasi format dengan perintah date) anda akan perlu untuk melarikan diri itu.
Yang lain baik gotchas berikut: http://www.pantz.org/software/cron/croninfo.html
Hal ini juga mungkin bahwa pengguna's sandi telah berakhir. Bahkan root's password bisa kadaluarsa. Anda dapat tail -f /var/log/cron.log
dan anda akan melihat cron gagal dengan password kadaluarsa. Anda dapat mengatur sandi untuk tidak pernah berakhir dengan melakukan hal ini: passwd -x -1 <username>
Dalam beberapa sistem (Debian, Ubuntu) pendataan untuk cron tidak diaktifkan secara default. Di /etc/rsyslog.conf atau /etc/rsyslog.d/50-default.conf line:
# cron.* /var/log/cron.log
harus diedit (sudo nano /etc/rsyslog.conf
) tanda komentar untuk:
cron.* /var/log/cron.log
Setelah itu, anda perlu me-restart rsyslog melalui
/etc/init.d/rsyslog restart
atau
service rsyslog restart
Sumber: Mengaktifkan crontab logging di Debian Linux
Dalam beberapa sistem (Ubuntu) terpisah log file untuk cron tidak diaktifkan secara default, tetapi cron terkait log yang muncul di file syslog. Satu dapat menggunakan
cat /var/log/syslog | grep cron -i
untuk melihat cron-pesan terkait.
Permissions masalah yang cukup umum, saya'm takut.
Perhatikan bahwa solusi umum ini adalah untuk melaksanakan segala sesuatu menggunakan root's crontab, yang kadang-kadang benar-Benar Ide yang Buruk. Pengaturan izin yang tepat pasti sebagian besar diabaikan masalah.
Cron table rejected jika izin ini tidak aman
sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)
Masalah ini diselesaikan dengan
# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs
Script lokasi-sensitif. Hal ini terkait untuk selalu menggunakan jalur mutlak dalam naskah, tapi tidak persis sama. Anda cron job mungkin perlu untuk cd
ke direktori tertentu sebelum menjalankan, misalnya menyapu tugas pada aplikasi Rails mungkin perlu dalam aplikasi root untuk Menyapu untuk menemukan yang benar tugas, tidak lagi sesuai konfigurasi database, dll.
Jadi crontab masuknya
23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=produksi
akan lebih baik sebagai
23 3 * * * cd /var/www/produksi/arus && /usr/bin/rake db:session_purge RAILS_ENV=produksi
Atau, untuk menjaga crontab entri sederhana dan kurang rapuh:
23 3 * * * /home/<user>/scripts/session-purge.sh
dengan kode berikut di /home/<user>/scripts/session-purge.sh
:
cd /var/www/produksi/saat ini /usr/bin/rake db:session_purge RAILS_ENV=produksi
Crontab spesifikasi yang bekerja di masa lalu bisa istirahat ketika pindah dari satu crontab file lain. Kadang-kadang alasannya adalah bahwa anda've pindah spec dari sistem file crontab untuk user crontab file atau sebaliknya.
Cron job spesifikasi format yang berbeda antara pengguna' crontab file (/var/spool/cron/username atau /var/spool/cron/crontabs/username) dan sistem crontabs (/etc/crontab
dan file-file di /etc/cron.d
).
Sistem crontabs memiliki bidang ekstra 'user' tepat sebelum perintah-to-run.
Hal ini akan menyebabkan kesalahan yang menyatakan hal-hal seperti george, perintah tidak ditemukan
ketika anda memindahkan perintah keluar dari /etc/crontab
atau file /etc/cron.d
ke pengguna's file crontab.
Sebaliknya, cron akan memberikan kesalahan seperti /usr/bin/restartxyz adalah tidak valid username
atau serupa ketika sebaliknya terjadi.
script cron adalah menjalankan perintah dengan --verbose pilihan
Saya punya script cron gagal pada saya karena saya berada di autopilot saat mengetik naskah dan saya termasuk --verbose pilihan:
#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands
Script ran baik-baik saja ketika mengeksekusi dari shell, tapi gagal ketika berjalan dari crontab karena verbose output pergi ke stdout ketika lari dari shell, tapi mana ketika lari dari crontab. Perbaiki mudah untuk menghapus 'v':
#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands
Satu alasan yang paling sering saya telah melihat cron gagal dalam salah dinyatakan jadwal. Hal ini membutuhkan latihan untuk menentukan pekerjaan yang dijadwalkan pada 11:15 pm sebagai 15 23 * * *
bukannya * * 11 15 *
atau 11 15 * * *
. Hari minggu untuk pekerjaan setelah tengah malam juga bingung M-F 2-6
setelah tengah malam, tidak 1-5
. Tanggal-tanggal tertentu biasanya masalah karena kita jarang menggunakannya * * 3 1 *
tidak 3 Maret. Jika anda tidak yakin, periksa cron jadwal online di https://crontab.guru/.
Jika anda bekerja dengan platform yang berbeda menggunakan pasangan pilihan seperti 2/3
dalam waktu spesifikasi juga dapat menyebabkan kegagalan. Ini adalah pilihan yang sangat berguna tetapi tidak tersedia secara universal. Saya juga telah menjalankan seluruh masalah dengan daftar seperti 1-5
atau 1,3,5
.
Menggunakan wajar tanpa pengecualian jalan juga menyebabkan masalah. Default path biasanya /bin:/usr/bin
sehingga hanya standar perintah yang akan dijalankan. Direktori ini biasanya don't memiliki perintah yang diinginkan. Hal ini juga mempengaruhi script menggunakan non-perintah standar. Lingkungan variabel lain juga bisa hilang.
Clobbering yang ada crontab seluruhnya telah menyebabkan saya masalah. Sekarang saya load dari file copy. Hal ini dapat pulih dari yang ada crontab menggunakan crontab -l
jika itu akan musnah. Aku menyimpan copy dari crontab di ~/bin. Komentar semua dan berakhir dengan garis # EOF
. Ini adalah reloaded sehari-hari dari crontab entri seperti:
#!/usr/bin/crontab # Ulang ini crontab # 54 12 * * * ${HOME}/bin/crontab
Reload perintah di atas bergantung pada eksekusi crontab dengan bang path menjalankan crontab. Beberapa sistem memerlukan menjalankan crontab di perintah dan menentukan file. Jika direktori jaringan berbagi, maka saya sering menggunakan crontab.$(hostname)
sebagai nama file. Hal ini pada akhirnya akan benar kasus-kasus di mana salah crontab dimuat pada server yang salah.
Menggunakan file menyediakan cadangan dari apa yang crontab harus, dan memungkinkan sementara suntingan (satu-satunya waktu saya menggunakan crontab -e
) akan mundur secara otomatis. Ada header yang tersedia yang membantu dengan mendapatkan parameter penjadwalan yang tepat. Saya telah menambahkan mereka ketika pengguna berpengalaman akan mengedit crontab.
Jarang, aku berjalan ke dalam perintah-perintah yang memerlukan input pengguna. Ini gagal dalam crontab, meskipun beberapa akan bekerja dengan input redirection.
Jika anda mengakses akun melalui SSH keys adalah mungkin untuk login ke akun tetapi tidak melihat bahwa password pada akun yang terkunci (misalnya karena berakhir atau password tidak valid upaya)
Jika sistem ini menggunakan PAM dan akun yang terkunci, hal ini dapat menghentikan cronjob dari berjalan. (Saya've diuji ini pada Solaris, tetapi tidak pada Ubuntu)
Anda mungkin menemukan pesan seperti ini di /var/adm/messages:
Oct 24, 07:51:00 mybox cron[29024]: [ID 731128 auth.pemberitahuan] pam_unix_account: cron mencoba untuk memvalidasi terkunci akun myuser dari host lokal Oct 24, 07:52:00 mybox cron[29063]: [ID 731128 auth.pemberitahuan] pam_unix_account: cron mencoba untuk memvalidasi terkunci akun myuser dari host lokal Oct 24, 07:53:00 mybox cron[29098]: [ID 731128 auth.pemberitahuan] pam_unix_account: cron mencoba untuk memvalidasi terkunci akun myuser dari host lokal Oct 24 07:54:00 mybox cron[29527]: [ID 731128 auth.pemberitahuan] pam_unix_account: cron mencoba untuk memvalidasi terkunci akun myuser dari host lokal
Semua anda harus perlu lakukan adalah menjalankan:
# passwd -u <USERNAME>
sebagai root untuk membuka rekening, dan crontab harus bekerja lagi.
Jika anda memiliki perintah seperti ini:
* * * * * /path/to/script >> /tmp/output
dan itu doesn't bekerja dan anda dapat't melihat output, hal itu mungkin tidak selalu berarti cron isn't bekerja. Script bisa rusak dan output akan stderr yang doesn't mendapatkan diteruskan ke /tmp/output. Check this isn't kasus, dengan menangkap output ini juga:
* * * * * /path/to/script >> /tmp/output 2>&1
untuk melihat apakah ini membantu anda menangkap masalah anda.
Saya sedang menulis menginstal shell script yang menciptakan script yang lain untuk membersihkan tua transaksi data dari database. Sebagai bagian dari tugas itu harus mengkonfigurasi sehari-hari cron
pekerjaan untuk dijalankan pada sembarang waktu, ketika database beban rendah.
Saya membuat sebuah file mycronjob
dengan cron jadwal, username & perintah dan disalin ke /etc/cron.d
direktori. Saya dua gotchas:
mycronjob
file yang harus dimiliki oleh root untuk menjalankanMasalah izin akan muncul di /var/log/syslog
sebagai sesuatu yang mirip dengan:
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)
Baris pertama mengacu pada /etc/crontab
file dan kemudian ke file saya ditempatkan di bawah /etc/cront.d
.