Seringkali, crontab
skrip tidak dieksekusi sesuai jadwal atau seperti yang diharapkan. Ada banyak alasan untuk itu:
- notasi crontab yang salah
- masalah izin
- variabel lingkungan
Wiki komunitas ini bertujuan untuk mengumpulkan alasan utama agar crontab
skrip tidak dieksekusi seperti yang diharapkan. Tuliskan setiap alasan dalam jawaban yang terpisah.
Harap sertakan satu alasan per jawaban - detail tentang mengapa itu tidak dijalankan - dan perbaiki karena satu alasan itu.
Harap tulis hanya masalah spesifik-cron, mis. Perintah yang dijalankan seperti yang diharapkan dari shell tetapi dieksekusi secara keliru oleh cron.
crontab -e
agar cron berlaku. Misalnya menggunakan vim saya mengedit file dan menggunakannya:w
untuk menulisnya tetapi pekerjaan tidak ditambahkan ke cron sampai saya berhenti juga. Jadi saya tidak akan melihat pekerjaan sampai setelah saya:q
juga.Jawaban:
Lingkungan yang berbeda
Cron melewati serangkaian variabel lingkungan minimal ke pekerjaan Anda. Untuk melihat perbedaannya, tambahkan pekerjaan tiruan seperti ini:
Tunggu
/tmp/env.output
hingga dibuat, lalu hapus pekerjaan itu lagi. Sekarang bandingkan konten/tmp/env.output
dengan outputenv
run di terminal reguler Anda."Gotcha" yang umum di sini adalah
PATH
variabel lingkungan yang berbeda. Mungkin skrip cron Anda menggunakan perintahsomecommand
ditemukan di/opt/someApp/bin
, yang telah Anda tambahkan kePATH
dalam/etc/environment
? cron mengabaikanPATH
dari file itu, jadi runnningsomecommand
dari skrip Anda akan gagal ketika dijalankan dengan cron, tetapi bekerja ketika dijalankan di terminal. Ini perlu dicatat bahwa variabel dari/etc/environment
akan diteruskan ke pekerjaan cron, hanya saja tidak variabel cron khusus set sendiri, sepertiPATH
.Untuk menyiasatinya, cukup atur
PATH
variabel Anda sendiri di bagian atas skrip. MisalnyaBeberapa lebih suka menggunakan jalur absolut untuk semua perintah saja. Saya merekomendasikan hal itu. Pertimbangkan apa yang terjadi jika Anda ingin menjalankan skrip Anda pada sistem yang berbeda, dan pada sistem itu, perintahnya ada
/opt/someAppv2.2/bin
. Anda harus membaca seluruh skrip untuk menggantikannya, alih/opt/someApp/bin
-/opt/someAppv2.2/bin
alih hanya melakukan edit kecil pada baris pertama skrip.Anda juga dapat mengatur variabel PATH dalam file crontab, yang akan berlaku untuk semua pekerjaan cron. Misalnya
sumber
env
, saya benar-benar lupa tentang perintah itu dan berpikir PATH berfungsi. Sebenarnya sedikit berbeda dalam kasus saya.Gotcha teratas saya: 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):sumber
man crontab
di Ubuntu 10.10 mengatakan "cron mensyaratkan bahwa setiap entri di crontab diakhiri dengan karakter baris baru. Jika entri terakhir di crontab tidak ada baris baru, cron akan mempertimbangkan crontab (setidaknya sebagian) rusak dan menolak untuk menginstalnya. " (Dan tanggalnya adalah 19 April 2010.)crontab -e
akan memeriksa sintaks file sebelum mengizinkan penyimpanan, termasuk pemeriksaan untuk baris baru.-e
opsi, dan independen dari editor.Daemon Cron tidak berjalan. Saya benar-benar mengacaukan ini beberapa bulan yang lalu.
Tipe:
Jika Anda tidak melihat nomor, maka cron tidak berjalan.
sudo /etc/init.d/cron start
dapat digunakan untuk memulai cron.EDIT: Daripada menggunakan skrip init melalui /etc/init.d, gunakan utilitas layanan, mis
EDIT: Anda juga dapat menggunakan systemctl di Linux modern, mis
sumber
pidof cron
yang akan menghilangkan hasil untuk aplikasi lain yang juga memiliki kata 'cron', seperti crontab.sudo service cron start
saya dapatkanstart: Job is already running: cron
service crond start
if its centos / RHELScript nama file di
cron.d/
,cron.daily/
,cron.hourly/
, dll, harus tidak mengandung titik (.
), jika tidak menjalankan-bagian akan melewatkan mereka.Lihat run-parts (8):
Jadi, jika Anda memiliki skrip cron
backup.sh
,analyze-logs.pl
dalamcron.daily/
direktori, sebaiknya hapus nama ekstensi.sumber
run-parts --test
(atau opsi imajiner lain seperti--debug
akan menampilkan file yang dilewati termasuk alasannya.Dalam banyak lingkungan cron mengeksekusi perintah menggunakan
sh
, sementara banyak orang menganggap itu akan digunakanbash
.Saran untuk menguji atau memperbaiki ini untuk perintah yang gagal:
Coba jalankan perintah
sh
untuk melihat apakah itu berfungsi:Bungkus perintah dalam subshell bash untuk memastikan itu dijalankan di bash:
Beri tahu cron untuk menjalankan semua perintah dalam bash dengan mengatur shell di bagian atas crontab Anda:
Jika perintahnya adalah skrip, pastikan skrip berisi shebang:
sumber
bash
, tetapi tidak dengancron
. Terima kasih!source
dalam bash tetapi tidak sh. Dalam cron / sh, gunakan periode:. envfile
daripadasource envfile
.sh "mycommand"
memberitahush
untuk menjalankan perintah saya sebagai file skrip. Apakah maksud Andash -c "mycommand"
? Bagaimanapun, jawaban ini tampaknya tentang membuat perintah dijalankan di bash khusus, jadi mengapa Anda menambahkan perintah untuk dish
sini?Saya memiliki beberapa masalah dengan zona waktu. Cron berjalan dengan zona waktu instalasi baru. Solusinya adalah me-restart cron:
sumber
* * * * * touch /tmp/cronworks
tidak melakukan apa pun, namun adaRELOAD
di cronlog.Path absolut harus digunakan untuk skrip:
Misalnya,
/bin/grep
harus digunakan daripadagrep
:Dari pada:
Ini sangat sulit, karena perintah yang sama akan berfungsi ketika dijalankan dari shell. Alasannya adalah bahwa
cron
tidak memilikiPATH
variabel lingkungan yang sama dengan pengguna.sumber
/usr/bin/whatever
path lengkapJika perintah crontab Anda memiliki
%
simbol di dalamnya, cron mencoba menafsirkannya. Jadi, jika Anda menggunakan perintah dengan%
di dalamnya (seperti spesifikasi format ke perintah tanggal), Anda harus menghindarinya.Itu dan Gotcha baik lainnya di sini:
http://www.pantz.org/software/cron/croninfo.html
sumber
date
bagian dalam pekerjaan tab cron?Cron memanggil skrip yang tidak dapat dieksekusi.
Dengan menjalankan
chmod +x /path/to/scrip
skrip menjadi executable dan harus menyelesaikan masalah ini.sumber
cron
, dan mudah dilacak dengan hanya mencoba mengeksekusi/path/to/script
dari baris perintah.. scriptname
ataush scriptname
ataubash scriptname
, maka ini menjadicron
masalah -specific.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>
Di beberapa sistem (Debian, Ubuntu) logging untuk cron tidak diaktifkan secara default. Di /etc/rsyslog.conf atau /etc/rsyslog.d/50-default.conf baris:
harus diedit (
sudo nano /etc/rsyslog.conf
) dihapus komentarnya untuk:Setelah itu, Anda harus memulai ulang rsyslog via
atau
Sumber: Aktifkan pencatatan crontab di Debian Linux
Dalam beberapa sistem (Ubuntu) file logging yang terpisah untuk cron tidak diaktifkan secara default, tetapi cron log terkait muncul dalam file syslog. Seseorang dapat menggunakan
untuk melihat pesan terkait cron.
sumber
Jika cronjob Anda memanggil aplikasi GUI, Anda perlu memberi tahu mereka TAMPILAN apa yang harus mereka gunakan.
Contoh: Peluncuran Firefox dengan cron.
Script Anda harus mengandung
export DISPLAY=:0
suatu tempat.sumber
* * * * * export DISPLAY=:0 && <command>
Masalah izin cukup umum, saya khawatir.
Perhatikan bahwa solusi umum adalah untuk mengeksekusi semuanya menggunakan crontab root, yang terkadang merupakan Ide yang Benar-benar Buruk. Menetapkan izin yang tepat jelas merupakan masalah yang sebagian besar diabaikan.
sumber
Izin tabel cron tidak aman
Tabel cron ditolak jika izinnya tidak aman
Masalahnya diselesaikan dengan
sumber
Skrip peka terhadap lokasi. Ini terkait dengan selalu menggunakan jalur absolut dalam skrip, tetapi tidak persis sama. Pekerjaan cron Anda mungkin perlu ke
cd
direktori tertentu sebelum menjalankan, mis. Tugas rake pada aplikasi Rails mungkin perlu berada di root aplikasi agar Rake menemukan tugas yang benar, belum lagi konfigurasi database yang sesuai, dll.Jadi entri crontab dari
23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production
akan lebih baik
Atau, untuk membuat entri crontab lebih sederhana dan tidak rapuh:
23 3 * * * /home/<user>/scripts/session-purge.sh
dengan kode berikut di
/home/<user>/scripts/session-purge.sh
:sumber
chdir(dirname(__FILE__));
Spesifikasi Crontab yang berfungsi di masa lalu dapat rusak ketika dipindahkan dari satu file crontab ke yang lain. Terkadang alasannya adalah Anda telah memindahkan spek dari file sistem crontab ke file pengguna crontab atau sebaliknya.
Format spesifikasi pekerjaan cron berbeda antara file crontab pengguna (/ var / spool / cron / nama pengguna atau / var / spool / cron / crontab / nama pengguna) dan crontab sistem (
/etc/crontab
dan file-file di dalamnya/etc/cron.d
).Sistem crontab memiliki bidang 'pengguna' tambahan tepat sebelum perintah dijalankan.
Ini akan menyebabkan kesalahan yang menyatakan hal-hal seperti
george; command not found
ketika Anda memindahkan perintah/etc/crontab
atau file/etc/cron.d
ke dalam file crontab pengguna.Sebaliknya, cron akan menghasilkan kesalahan seperti
/usr/bin/restartxyz is not a valid username
atau serupa ketika terjadi kebalikannya.sumber
skrip cron menjalankan perintah dengan opsi --verbose
Saya mengalami gagal pada skrip cron karena saya menggunakan autopilot saat mengetik skrip dan saya menyertakan opsi --verbose:
Script berjalan dengan baik ketika mengeksekusi dari shell, tetapi gagal ketika menjalankan dari crontab karena output verbose pergi ke stdout ketika dijalankan dari shell, tetapi tidak ketika dijalankan dari crontab. Perbaikan mudah untuk menghapus 'v':
sumber
Alasan paling sering saya melihat cron gagal dalam jadwal yang salah. Dibutuhkan latihan untuk menentukan pekerjaan yang dijadwalkan pukul 11:15 malam sebagai
15 23 * * *
ganti* * 11 15 *
atau11 15 * * *
. Hari dalam seminggu untuk pekerjaan setelah tengah malam juga menjadi bingung MF adalah2-6
setelah tengah malam, bukan1-5
. Tanggal spesifik biasanya menjadi masalah karena kita jarang menggunakannya* * 3 1 *
bukan tanggal 3 Maret. Jika Anda tidak yakin, periksa jadwal cron Anda secara online di https://crontab.guru/ .Jika pekerjaan Anda dengan platform berbeda menggunakan opsi yang tidak didukung seperti
2/3
dalam spesifikasi waktu juga dapat menyebabkan kegagalan. Ini adalah opsi yang sangat berguna tetapi tidak tersedia secara universal. Saya juga mengalami masalah dengan daftar seperti1-5
atau1,3,5
.Menggunakan jalur yang tidak memenuhi syarat juga menyebabkan masalah. Path default biasanya
/bin:/usr/bin
jadi hanya perintah standar yang akan berjalan. Direktori ini biasanya tidak memiliki perintah yang diinginkan. Ini juga mempengaruhi skrip yang menggunakan perintah non-standar. Variabel lingkungan lainnya juga bisa hilang.Memukul crontab yang ada sepenuhnya telah menyebabkan masalah bagi saya. Saya sekarang memuat dari salinan file. Ini dapat dipulihkan dari crontab yang ada menggunakan
crontab -l
jika akan musnah. Saya menyimpan salinan crontab di ~ / bin. Itu dikomentari sepanjang dan berakhir dengan garis# EOF
. Ini dimuat ulang setiap hari dari entri crontab seperti:Perintah reload di atas bergantung pada crontab yang dapat dieksekusi dengan bang path menjalankan crontab. Beberapa sistem membutuhkan crontab yang sedang berjalan dalam perintah dan menentukan file. Jika direktori tersebut dibagi-pakai oleh jaringan, maka saya sering menggunakan
crontab.$(hostname)
sebagai nama file. Ini pada akhirnya akan memperbaiki kasus di mana crontab yang salah dimuat pada server yang salah.Menggunakan file menyediakan cadangan apa yang seharusnya crontab, dan memungkinkan pengeditan sementara (satu-satunya waktu saya gunakan
crontab -e
) untuk mundur secara otomatis. Ada tajuk yang tersedia yang membantu mengatur parameter penjadwalan dengan benar. Saya telah menambahkan mereka ketika pengguna yang tidak berpengalaman akan mengedit crontab.Jarang, saya telah menjalankan perintah yang membutuhkan input pengguna. Ini gagal di bawah crontab, meskipun beberapa akan bekerja dengan pengalihan input.
sumber
30 23 * * *
menterjemahkan ke 11:15?15 23 * * *
. Diperbaiki sekarang.Jika Anda mengakses akun melalui kunci SSH dimungkinkan untuk masuk ke akun tetapi tidak melihat bahwa kata sandi pada akun tersebut terkunci (mis. Karena upaya kata sandi yang kedaluwarsa atau tidak valid)
Jika sistem menggunakan PAM dan akun terkunci, ini dapat menghentikan cronjobnya agar tidak berjalan. (Saya sudah menguji ini pada Solaris, tetapi tidak pada Ubuntu)
Anda dapat menemukan pesan seperti ini di / var / adm / messages:
Yang harus Anda lakukan adalah menjalankan:
sebagai root untuk membuka kunci akun, dan crontab akan bekerja lagi.
sumber
Jika Anda memiliki perintah seperti ini:
dan itu tidak bekerja dan Anda tidak dapat melihat output apa pun, itu mungkin tidak berarti cron tidak berfungsi. Script bisa rusak dan output akan stderr yang tidak diteruskan ke / tmp / output. Periksa ini bukan masalahnya, dengan menangkap output ini juga:
untuk melihat apakah ini membantu Anda menangkap masalah Anda.
sumber
=== Peringatan Docker ===
Jika Anda menggunakan buruh pelabuhan,
Saya pikir pantas untuk menambahkan bahwa saya tidak bisa membuat cron berjalan di latar belakang.
Untuk menjalankan pekerjaan cron di dalam wadah, saya menggunakan penyelia dan berlari
cron -f
, bersama dengan proses lainnya.Sunting: Masalah lain - Saya juga tidak berhasil membuatnya bekerja saat menjalankan wadah dengan jaringan HOST. Lihat masalah ini di sini juga: https://github.com/phusion/baseimage-docker/issues/144
sumber
Saya sedang menulis skrip instalasi shell yang membuat skrip lain untuk membersihkan data transaksi lama dari database. Sebagai bagian dari tugas itu harus mengkonfigurasi
cron
pekerjaan harian untuk dijalankan pada waktu yang sewenang-wenang, ketika beban basis data rendah.Saya membuat file
mycronjob
dengan jadwal cron, nama pengguna & perintah dan menyalinnya ke/etc/cron.d
direktori. Dua gotcha saya:mycronjob
file harus dimiliki oleh root untuk menjalankanMasalah izin akan muncul
/var/log/syslog
sebagai sesuatu yang mirip dengan:Baris pertama merujuk ke
/etc/crontab
file dan kemudian ke file yang saya tempatkan di bawah/etc/cront.d
.sumber
Baris yang ditulis dengan cara crontab tidak mengerti. Itu harus ditulis dengan benar. Inilah CrontabHowTo .
sumber
Cron daemon bisa berjalan, tetapi tidak benar-benar berfungsi. Coba mulai ulang cron:
sumber
pidof
cron dan tidak mendapatkan apa-apa.service
Sudah mencoba menggunakan utilitas dan katanya cron sudah berjalan. Hanya jalankan perintah ini dan jalankanpidof
lagi dan saya mendapatkan hasil.Menulis ke cron melalui "crontab -e" dengan argumen nama pengguna dalam satu baris. Saya telah melihat contoh pengguna (atau sysadmin) menulis skrip shell mereka dan tidak mengerti mengapa mereka tidak mengotomatisasi. Argumen "pengguna" ada di / etc / crontab, tetapi bukan file yang ditentukan pengguna. jadi, misalnya, file pribadi Anda akan menjadi seperti:
sedangkan / etc / crontab adalah:
Jadi, mengapa Anda melakukan yang terakhir? Nah, tergantung pada bagaimana Anda ingin mengatur izin Anda, ini bisa menjadi sangat berbelit-belit. Saya telah menulis skrip untuk mengotomatisasi tugas-tugas bagi pengguna yang tidak memahami seluk-beluknya, atau tidak ingin repot dengan pekerjaan yang membosankan. Dengan mengatur izin
--x------
, saya dapat membuat skrip dapat dieksekusi tanpa mereka dapat membacanya (dan mungkin tanpa sengaja mengubahnya). Namun, saya mungkin ingin menjalankan perintah ini dengan beberapa orang lain dari satu file (sehingga membuatnya lebih mudah untuk dipelihara) tetapi pastikan output file ditentukan oleh pemilik yang tepat. Melakukannya (setidaknya di Ubuntu 10.10) memecah kedua ketidakmampuan untuk membaca file serta mengeksekusi, ditambah masalah yang disebutkan sebelumnya dengan meletakkan periode di / etc / crontab (yang, anehnya, tidak menyebabkan kesalahan saat melaluicrontab -e
) .Sebagai contoh, saya telah melihat contoh
sudo crontab -e
digunakan untuk menjalankan skrip dengan izin root, dengan yang sesuaichown username file_output
dalam skrip shell. Ceroboh, tetapi berhasil. IMHO, Pilihan yang lebih anggun adalah memasukkannya/etc/crontab
dengan nama pengguna dinyatakan dan izin yang tepat, jadifile_output
pergi ke tempat dan pemilik yang tepat.sumber
Membangun apa yang Aaron Peart sebutkan tentang mode verbose, kadang-kadang skrip yang tidak dalam mode verbose akan menginisialisasi tetapi tidak selesai jika perilaku default dari perintah yang disertakan adalah untuk menampilkan baris atau lebih ke layar setelah proc dimulai. Sebagai contoh, saya menulis skrip cadangan untuk intranet kami yang menggunakan curl, sebuah utilitas yang mengunduh atau mengunggah file ke server jarak jauh, dan sangat berguna jika Anda hanya dapat mengakses file jarak jauh tersebut melalui HTTP. Menggunakan 'curl http://something.com/somefile.xls ' menyebabkan skrip yang saya tulis hang dan tidak pernah selesai karena meludahkan baris baru diikuti oleh garis kemajuan. Saya harus menggunakan flag bisu (-s) untuk mengatakannya agar tidak menampilkan informasi apa pun, dan menulis dalam kode saya sendiri untuk menangani jika file gagal diunduh.
sumber
/dev/null
. Sebagai contoh:some-command > /dev/null
Ini hanya akan mengarahkan output standar, dan bukan output kesalahan (yang biasanya Anda inginkan, karena Anda ingin mendapat informasi tentang kesalahan). Untuk mengalihkan output kesalahan juga, gunakansome-command &> /dev/null
.Meskipun Anda dapat mendefinisikan variabel lingkungan di crontable Anda, Anda tidak berada dalam skrip shell. Jadi konstruksi seperti berikut ini tidak akan berfungsi:
Ini karena variabel tidak diinterpretasikan dalam crontable: semua nilai diambil secara litteral. Dan ini sama jika Anda menghilangkan tanda kurung. Jadi perintah Anda tidak akan berjalan, dan file log Anda tidak akan ditulis ...
Alih-alih, Anda harus mendefinisikan semua variabel lingkungan Anda secara langsung:
sumber
Ketika tugas dijalankan dalam cron, stdin ditutup. Program yang bertindak berbeda berdasarkan apakah stdin tersedia atau tidak akan berperilaku berbeda antara sesi shell dan dalam cron.
Contohnya adalah program
goaccess
untuk menganalisis file log server web. Ini TIDAK berfungsi di cron:dan
goaccess
menunjukkan halaman bantuan alih-alih membuat laporan. Dalam shell ini dapat direproduksi denganCara mengatasinya
goaccess
adalah membuatnya membaca log dari stdin alih-alih membaca dari file, jadi solusinya adalah mengubah entri crontab menjadisumber
Dalam kasus saya cron dan crontab memiliki pemilik berbeda.
TIDAK berfungsi, saya punya ini:
Pada dasarnya saya harus menjalankan cron-config dan menjawab pertanyaan dengan benar. Ada titik di mana saya diminta untuk memasukkan kata sandi pengguna Win7 untuk akun 'Pengguna' saya. Dari membaca yang saya lakukan, sepertinya ini adalah masalah keamanan potensial tetapi saya satu-satunya administrator di satu jaringan rumah jadi saya memutuskan tidak apa-apa.
Berikut adalah urutan perintah yang membuat saya aktif:
sumber
Di server RHEL7 saya, pekerjaan root cron akan berjalan, tetapi pekerjaan pengguna tidak. Saya menemukan bahwa tanpa direktori home, pekerjaan tidak akan berjalan (tetapi Anda akan melihat kesalahan yang baik di / var / log / cron). Ketika saya membuat direktori home, masalahnya terpecahkan.
sumber
Jika Anda mengedit file crontab Anda menggunakan editor windows (melalui samba atau sesuatu) dan itu menggantikan baris baru dengan \ n \ r atau hanya \ r, cron tidak akan berjalan.
Juga, jika Anda menggunakan /etc/cron.d/* dan salah satu dari file-file itu memiliki \ r di dalamnya, cron akan bergerak di seluruh file dan berhenti ketika menyentuh file yang buruk. Tidak yakin apakah itu masalahnya?
Menggunakan:
sumber