Pertanyaan Mengapa skrip crontab tidak berfungsi?


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

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

Komunitas ini bertujuan untuk mengumpulkan alasan utama crontab skrip tidak dieksekusi seperti yang diharapkan. Tuliskan setiap alasan dalam jawaban yang berbeda.

Harap sertakan satu alasan per jawaban - detail tentang mengapa itu tidak dilaksanakan - dan perbaiki (es) untuk satu alasan itu.

Harap tulis hanya masalah khusus cron, mis. perintah yang dieksekusi seperti yang diharapkan dari shell tetapi dieksekusi secara salah oleh cron.


454


asal


Anda harus menutup crontab -e agar cron terpengaruh. 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. - DutGRIFF
Saya pikir cara terbaik untuk debug cron adalah dengan memeriksa syslog dan menemukan masalah. - Suneel Kumar
Dalam kasus saya - email itu akan ke folder SPAM saya, jadi ..... periksa bahwa sebelum Anda menghabiskan berjam-jam di debugging: D - almaruf
Listrik padam - Josef Klimuk


Jawaban:


Lingkungan yang berbeda

Cron mengirimkan sejumlah variabel lingkungan minimal ke pekerjaan Anda. Untuk melihat perbedaannya, tambahkan pekerjaan tiruan seperti ini:

* * * * * env> /tmp/env.output

Tunggu sebentar /tmp/env.output untuk dibuat, lalu hapus pekerjaan itu lagi. Sekarang bandingkan isi /tmp/env.output dengan output env jalankan di terminal reguler Anda.

"Gotcha" umum 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 ketika dijalankan dengan cron, tetapi bekerja ketika dijalankan di terminal. Ini perlu dicatat bahwa variabel dari /etc/environment akan diteruskan ke cron jobs, tidak hanya variabel cron yang secara spesifik mengatur dirinya sendiri, seperti PATH.

Untuk menyiasati itu, cukup tetapkan sendiri PATH variabel di bagian atas skrip. Misalnya.

#!/bin/bash
PATH=/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 untuk semua perintah sebagai gantinya. Saya merekomendasikan hal itu. Pertimbangkan apa yang terjadi jika Anda ingin menjalankan skrip Anda pada sistem yang berbeda, dan pada sistem itu, perintahnya masuk /opt/someAppv2.2/bin sebagai gantinya. Anda harus melalui seluruh skrip yang diganti /opt/someApp/bin dengan /opt/someAppv2.2/bin daripada hanya melakukan pengeditan kecil di baris pertama skrip.

Anda juga dapat mengatur variabel PATH di 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:/bin

15 1 * * * backupscript --incremental /home /root

431



Saya pikir saya hanya jatuh untuk ini, dan baris baru di akhir ... ganda whammy. - WernerCD
+1 untuk envSaya benar-benar lupa tentang perintah itu dan berpikir bahwa PATH bekerja. Itu sebenarnya agak berbeda dalam kasus saya. - Izkata
@pbr Jika direktori semacam itu dibiarkan dapat ditulisi oleh orang lain, sistem tersebut sudah dikompromikan. - geirha
@ pbr Sysadmin tanpa sadar dapat menghapus filesystem root. Anda tidak bisa berjaga terhadap sysadmin membuat kesalahan konyol. Jika Anda menginstal versi penerjemah yang lebih baru yang tidak kompatibel dengan ke belakang, saya harap kerusakan akan hilang. Cara yang waras untuk menangani itu adalah menginstalnya sebagai perintah yang berbeda. Misalnya. Anda memiliki versi python 2.x dan menginstal python 3, Anda menginstalnya sebagai python3, bukan python. Dan untuk / opt / someApp / bin, mengapa tidak memiliki izin / kepemilikan waras? admin yang waras akan memastikan izin / kepemilikan yang waras pada file sistem. - geirha
@pbr Sepertinya kita bisa terus selamanya, ya. Saya masih gagal untuk melihat mengapa itu ide yang buruk untuk menggunakan PATH sekalipun. Jika Anda ingin membahas hal ini lebih lanjut di media yang lebih cocok untuk diskusi, Anda akan menemukan saya di #ubuntu dan #bash, di antara saluran lain, di irc.freenode.net - geirha


Gotcha atas saya: Jika Anda lupa menambahkan baris baru di akhir crontab mengajukan. 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)

291



ini adalah showstopper seperti itu, kenapa belum diperbaiki dalam bertahun-tahun cron? - Capi Etheriel
Tampaknya diperbaiki dalam Vixie cron: man crontab pada Ubuntu 10.10 mengatakan "cron mensyaratkan setiap entri dalam crontab berakhir dengan karakter baris baru. Jika entri terakhir dalam crontab tidak memiliki baris baru, cron akan menganggap crontab (setidaknya sebagian) rusak dan menolak untuk menginstalnya." (Dan tanggal di akhir adalah 19 April 2010.) - Marius Gedminas
@barraponto Ini sebenarnya bug dalam editor teks baru. Karakter "baris baru" seharusnya adalah a pemutusan saluran karakter, sehingga baris terakhir dalam file teks seharusnya berakhir dengan karakter baris baru yang tidak ditampilkan dalam editor. Vi dan vim menggunakan karakter dengan benar, dan cron dibangun sebelum editor baru memulai perilaku aneh mereka ... Oleh karena itu bermainlah menyimpan dan termasuk garis kosong. - Izkata
Jika Anda mengedit menggunakan crontab crontab -e ini akan memeriksa sintaks file sebelum mengizinkan penyimpanan, termasuk pemeriksaan untuk baris baru. - Tom Harrison Jr
@ Chan-HoSuh, menurut halaman manual "cron mengharuskan setiap entri dalam crontab berakhir dengan karakter baris baru. Jika entri terakhir dalam crontab hilang baris baru, cron akan menganggap crontab (setidaknya sebagian) rusak dan menolak menginstalnya. " Perilaku ini akan dipanggil saat mengedit lalu menyimpan crontab menggunakan -e pilihan, dan tidak bergantung pada editor. - Tom Harrison Jr


Cron daemon tidak berjalan. Saya benar-benar gagal dengan ini beberapa bulan yang lalu.

Mengetik:

pgrep cron 

Jika Anda tidak melihat angka, cron tidak berjalan. sudo /etc/init.d/cron start dapat digunakan untuk memulai cron.

EDIT: Daripada memohon skrip init melalui /etc/init.d, gunakan layanan utilitas, mis.

sudo service cron start

125



Terima kasih telah menunjukkan saya pgrep. Saya terus melakukan psefe grep foo - ripper234
Anda juga bisa menggunakan pidof cron yang akan menghilangkan hasil untuk aplikasi lain yang juga memiliki kata 'cron', seperti crontab. - Pithikos
Aneh, semua ini tidak memberi saya apa-apa untuk menunjukkan cron sedang berjalan, tetapi jika saya jalankan sudo service cron start saya mendapat start: Job is already running: cron - Colleen
service crond start jika centos / RHEL nya - Srihari Karanth


Nama file skrip di cron.d/, cron.daily/, cron.hourly/, dll., tidak boleh mengandung titik (.), jika tidak, run-parts akan melewati 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 skrip cron backup.sh, analyze-logs.pl di cron.daily/ direktori, Anda sebaiknya menghapus nama ekstensi.


83



Ini adalah fitur bukan bug - itu membuat hal-hal seperti myscript.backup atau myscript.original atau myscript.rpm -baru dari berjalan tepat di samping myscript. - pbr
@pbr: masuk akal. Setidaknya itu akan sangat membantu untuk debugging jika run-parts --test (atau opsi imajiner lain seperti --debug akan menampilkan file yang dilewati termasuk alasannya. - Rabarberski
Jika ini adalah fitur, itu bukan yang bagus :( Banyak orang menggunakan dot dalam nama file (backup.sh adalah yang paling umum). Jika Anda ingin skrip untuk berhenti mengeksekusi, metode yang paling logis adalah hapus dari direktori "cron.d". - MatuDuke
Ini adalah fitur yang buruk bahwa itu adalah bug yang efektif. Ini adalah praktik umum untuk meminta suatu akhiran tertentu (seperti ".list" atau ".cron" atau sesuatu) jika orang ingin memastikan bahwa hal-hal hanya berjalan ketika dimaksudkan. Sewenang-wenang memilih titik sebagai pemisah kemungkinan untuk ".bak" atau ".temp" atau apa pun, benar-benar tidak dapat diprediksi kecuali dengan cara yang dapat diprediksi membingungkan orang. Akhir yang sah seperti ".sh", dan ".pl" telah digunakan secara luas selama beberapa dekade. Banyak orang menggunakan "_bak" atau "_temp" atau "-bak" sebagai ganti dot. Ini adalah pilihan desain yang mengerikan; itu adalah bug desain terbaik. - Teekin


Di banyak lingkungan, cron menjalankan perintah menggunakan sh, sementara banyak orang menganggap itu akan digunakan bash.

Saran untuk menguji atau memperbaiki ini untuk perintah yang gagal:

  • Coba jalankan perintah di sh untuk melihat apakah itu berhasil
  • Bungkus perintah dalam subkulit bash untuk memastikannya dijalankan di bash:
    bash -c "mybashcommand"
  • Beritahu 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

55



Saran bash sangat membantu, masalah tetap dengan cron saya. - Maxim Galushka
Ini hanya menyebabkan saya 1 jam fiddling / troubleshooting. Bahkan lebih membingungkan jika Anda tidak menyadari masalah ini adalah script akan berjalan secara manual baik-baik saja jika Anda shell khas bash, tapi tidak dengan cron. Terima kasih! - Hendy
Beberapa waktu yang lalu saya menemukan sesuatu yang berhubungan: Perintah source dalam bash tapi tidak sh. Dalam cron / sh, gunakan sebuah periode: . envfile daripada source envfile. - kungphu


Saya memiliki beberapa masalah dengan zona waktu. Cron berlari dengan zona waktu instalasi yang baru. Solusinya adalah memulai ulang cron:

sudo service cron restart

34



Ya, setelah mengubah zona waktu pada suatu sistem, seseorang harus me-restart setiap layanan yang peduli tentang jam berapa, atau reboot. Saya lebih suka reboot, untuk memastikan saya sudah menangkap semuanya. - pbr
Oh, demi Tuhan, membunuh jam di ini. Layanan ulang dimulai setelah * * * * * touch /tmp/cronworks tidak melakukan apa pun, namun ada RELOAD di cronlog. - НЛО


Jika perintah crontab Anda memiliki % simbol di dalamnya, cron mencoba menafsirkannya. Jadi jika Anda menggunakan perintah apa pun dengan % di dalamnya (seperti spesifikasi format untuk perintah tanggal) Anda harus meloloskannya.

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


29



Inilah yang menyebabkan tugas Cron saya gagal selama minggu terakhir. Akhirnya tahu bahwa Tanggal saya tidak memiliki karakter melarikan diri (backslash untuk orang lain yang mencari apa karakter melarikan diri). Yay! - Valien
Lihat juga Bagaimana saya bisa mengeksekusi date di dalam pekerjaan tab cron? - Jared Beck
Yang ini menggigitku juga. Terima kasih! - stefansundin


Jalur absolut harus digunakan untuk skrip:

Sebagai contoh, /bin/grep sebaiknya digunakan sebagai gantinya grep:

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

Dari pada:

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

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


28



lihat jawaban geirha, Anda dapat (harus) menentukan PATH cron - Capi Etheriel
Bzzt. Anda TIDAK perlu menentukan PATH - menggunakan path absolut adalah praktik terbaik di sini. "karena dapat dieksekusi di tempat lain di beberapa komputer lain" tidak truf "Saya ingin menjalankan program ini persis dan tidak ada orang lain yang ditempatkan di jalur di depan program asli saya" - pbr
Ya ini untuk saya, di luar cron saya bisa menjalankan perintah secara langsung, di dalam cron yang dibutuhkannya penuh /usr/bin/whatever jalan - Anentropic


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

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

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

harus diedit (sudo nano /etc/rsyslog.conf) tanpa komentar ke:

cron.*                          /var/log/cron.log

Setelah itu, Anda perlu me-restart rsyslog via

/etc/init.d/rsyslog restart

atau

service rsyslog restart 

Sumber: Aktifkan penebangan crontab di Debian Linux

Di beberapa sistem (Ubuntu) file penebangan terpisah untuk cron tidak diaktifkan secara default, tetapi log terkait cron muncul dalam file syslog. Satu dapat digunakan

cat /var/log/syslog | grep cron

untuk melihat pesan terkait cron.


23



Saya memiliki Debian (wheezy) tetapi tidak ada /etc/init.d/rsyslog, hanya inetutils-syslogd dan sysklogd. Apakah saya harus menginstal sesuatu atau hanya me-restart salah satu dari keduanya? - hgoebl