Mengapa skrip crontab tidak berfungsi?

525

Seringkali, crontabskrip tidak dieksekusi sesuai jadwal atau seperti yang diharapkan. Ada banyak alasan untuk itu:

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

Wiki komunitas ini bertujuan untuk mengumpulkan alasan utama agar crontabskrip 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.

Adam Matan
sumber
12
Anda harus menutup crontab -eagar cron berlaku. Misalnya menggunakan vim saya mengedit file dan menggunakannya :wuntuk menulisnya tetapi pekerjaan tidak ditambahkan ke cron sampai saya berhenti juga. Jadi saya tidak akan melihat pekerjaan sampai setelah saya :qjuga.
DutGRIFF
Saya pikir cara terbaik untuk men-debug cron adalah dengan memeriksa syslog dan menemukan masalahnya.
Suneel Kumar
Dalam kasus saya - email itu pergi ke folder SPAM saya, jadi ..... periksa sebelum Anda menghabiskan berjam-jam untuk debugging: D
almaruf
Pemadaman listrik
Josef Klimuk

Jawaban:

501

Lingkungan yang berbeda

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

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

Tunggu /tmp/env.outputhingga dibuat, lalu hapus pekerjaan itu lagi. Sekarang bandingkan konten /tmp/env.outputdengan output envrun di terminal reguler Anda.

"Gotcha" yang umum di sini adalah PATHvariabel lingkungan yang berbeda. Mungkin skrip cron Anda menggunakan perintah somecommandditemukan di /opt/someApp/bin, yang telah Anda tambahkan ke PATHdalam /etc/environment? cron mengabaikan PATHdari file itu, jadi runnning somecommanddari skrip Anda akan gagal ketika dijalankan dengan cron, tetapi bekerja ketika dijalankan di terminal. Ini perlu dicatat bahwa variabel dari /etc/environmentakan diteruskan ke pekerjaan cron, hanya saja tidak variabel cron khusus set sendiri, seperti PATH.

Untuk menyiasatinya, cukup atur PATHvariabel Anda sendiri 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 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/binalih 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

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root
geirha
sumber
5
Saya pikir saya hanya jatuh cinta untuk ini, dan baris baru pada akhirnya ... whammy ganda.
WernerCD
6
+1 untuk env, saya benar-benar lupa tentang perintah itu dan berpikir PATH berfungsi. Sebenarnya sedikit berbeda dalam kasus saya.
Izkata
8
@ pbr Jika direktori tersebut dibiarkan dapat ditulis oleh orang lain, sistem sudah dikompromikan.
geirha
6
@ pbr Sysadmin tanpa disadari dapat menghapus filesystem root. Anda tidak dapat menjaga terhadap sysadmin membuat kesalahan konyol. Jika Anda menginstal interpreter versi yang lebih baru yang tidak kompatibel ke belakang, saya harapkan kerusakannya terjadi. Cara yang waras untuk mengatasinya adalah dengan menginstalnya sebagai perintah yang berbeda. Misalnya Anda memiliki python versi 2.x dan menginstal python 3, Anda menginstalnya sebagai python3, bukan python. Dan untuk / opt / someApp / bin, mengapa tidak memiliki izin / kepemilikan yang waras? admin waras akan memastikan izin / kepemilikan waras pada file sistem.
geirha
2
@ pbr Sepertinya kita bisa pergi selamanya, ya. Saya masih gagal melihat mengapa ini ide yang buruk untuk menggunakan PATH. Jika Anda merasa ingin membahas ini lebih jauh dalam media yang lebih cocok untuk diskusi, Anda akan menemukan saya di #ubuntu dan #bash, di antara saluran lainnya, di irc.freenode.net
geirha
336

Gotcha teratas saya: Jika Anda lupa menambahkan baris baru di akhir crontabfile. Dengan kata lain, file crontab harus diakhiri dengan baris kosong.

Di bawah ini adalah bagian yang relevan di halaman manual untuk masalah ini ( man crontabkemudian 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)
pengguna4124
sumber
91
ini adalah showstopper, kenapa belum diperbaiki dalam bertahun-tahun cron?
Capi Etheriel
2
Tampaknya diperbaiki di Vixie cron: man crontabdi 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.)
Marius Gedminas
19
@barraponto Ini sebenarnya bug di editor teks baru. Karakter "baris baru" seharusnya menjadi karakter penghentian baris , sehingga baris terakhir dalam file teks seharusnya diakhiri dengan karakter baris baru yang tidak ditampilkan di editor. Vi dan vim menggunakan karakter dengan benar, dan cron dibangun sebelum editor baru memulai perilaku aneh mereka ... Oleh karena itu mainkan save dan termasuk baris kosong.
Izkata
6
Jika Anda mengedit crontab menggunakannya crontab -eakan memeriksa sintaks file sebelum mengizinkan penyimpanan, termasuk pemeriksaan untuk baris baru.
Tom Harrison Jr
2
@ Chan-HoSuh, menurut halaman manual "cron mensyaratkan bahwa setiap entri di crontab diakhiri dengan karakter baris baru. Jika entri terakhir di crontab tidak ada baris baru, cron akan menganggap crontab (setidaknya sebagian) rusak dan menolak untuk pasang itu. " Perilaku ini akan dipanggil saat mengedit kemudian menyimpan crontab menggunakan -eopsi, dan independen dari editor.
Tom Harrison Jr
139

Daemon Cron tidak berjalan. Saya benar-benar mengacaukan ini beberapa bulan yang lalu.

Tipe:

pgrep cron 

Jika Anda tidak melihat nomor, maka cron tidak berjalan. sudo /etc/init.d/cron startdapat digunakan untuk memulai cron.

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

sudo service cron start

EDIT: Anda juga dapat menggunakan systemctl di Linux modern, mis

sudo systemctl start cron
pengguna6019
sumber
47
Terima kasih sudah menunjukkan pgrep. Saya terus melakukan ps -ef | grep foo
ripper234
4
Anda juga dapat menggunakan pidof cronyang akan menghilangkan hasil untuk aplikasi lain yang juga memiliki kata 'cron', seperti crontab.
Pithikos
Aneh, semua ini memberi saya apa-apa untuk menunjukkan cron berjalan, tetapi jika saya menjalankan sudo service cron startsaya dapatkanstart: Job is already running: cron
Colleen
1
service crond startif its centos / RHEL
Srihari Karanth
91

Script 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):

   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.pldalam cron.daily/direktori, sebaiknya hapus nama ekstensi.

Xiè Jìléi
sumber
10
Ini adalah fitur bukan bug - itu membuat hal-hal seperti myscript.backup atau myscript.original atau myscript.rpm-baru dari menjalankan tepat di samping myscript.
pbr
@ pbr: masuk akal. Setidaknya itu akan membantu untuk debugging jika run-parts --test(atau opsi imajiner lain seperti --debugakan menampilkan file yang dilewati termasuk alasannya.
Rabarberski
9
Jika ini fitur, ini bukan fitur yang bagus :( Banyak orang menggunakan dot dalam nama file (backup.sh adalah yang paling umum). Jika Anda ingin skrip berhenti dijalankan, metode yang paling logis adalah dengan hapus dari direktori "cron.d"
MatuDuke
8
Ini adalah fitur yang buruk sehingga efektif sebagai bug. Ini adalah praktik umum untuk meminta akhiran tertentu (seperti ".list" atau ".cron" atau sesuatu) jika orang ingin memastikan bahwa segala sesuatunya hanya berjalan ketika dimaksudkan. Memilih titik secara sewenang-wenang sebagai pemisah yang mungkin untuk ".bak" atau ".temp" atau apa pun, benar-benar tidak dapat diprediksi kecuali dengan cara yang diprediksi akan membingungkan orang. Ujung yang sah seperti ".sh", dan ".pl" telah digunakan secara luas selama beberapa dekade. Namun, banyak orang menggunakan "_bak" atau "_temp" atau "-bak" alih-alih sebuah titik. Ini adalah pilihan desain yang buruk; itu bug desain yang terbaik.
Teekin
68

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

Saran untuk menguji atau memperbaiki ini untuk perintah yang gagal:

  • Coba jalankan perintah shuntuk melihat apakah itu berfungsi:

    sh -c "mycommand"
    
  • Bungkus perintah dalam subshell bash untuk memastikan itu dijalankan di bash:

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

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

    #!/bin/bash
    
Olorin
sumber
Saran bash sangat membantu, memperbaiki masalah dengan cron saya.
Maxim Galushka
Ini hanya menyebabkan saya 1 jam mengutak-atik / troubleshooting. Bahkan lebih membingungkan jika Anda tidak mengetahui masalah ini adalah skrip akan berjalan secara manual jika Anda tipikal shell bash, tetapi tidak dengan cron. Terima kasih!
Hendy
Beberapa waktu yang lalu saya bertemu dengan sesuatu yang berhubungan: Perintah sourcedalam bash tetapi tidak sh. Dalam cron / sh, gunakan periode: . envfiledaripada source envfile.
kungphu
@Clockwork sh "mycommand"memberitahu shuntuk menjalankan perintah saya sebagai file skrip. Apakah maksud Anda sh -c "mycommand"? Bagaimanapun, jawaban ini tampaknya tentang membuat perintah dijalankan di bash khusus, jadi mengapa Anda menambahkan perintah untuk di shsini?
Olorin
@Olorin Dari pemahaman saya, tujuan dari poin pertama adalah untuk mencoba dan menjalankannya dengan sh, untuk melihat apakah masalahnya benar-benar berasal dari fakta bahwa cron menjalankannya dengan sh bukannya bash. Kemudian lagi, saya hanya memiliki sedikit pengetahuan tentang masalah ini, jadi saya mungkin salah.
Clockwork
40

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

sudo service cron restart
Luissquall
sumber
6
Ya, setelah mengubah zona waktu pada suatu sistem, seseorang harus memulai kembali setiap layanan yang peduli tentang jam berapa sekarang, atau memulai ulang. Saya lebih suka reboot, untuk memastikan saya sudah menangkap semuanya.
pbr
Oh, demi Tuhan, menghabiskan berjam-jam dalam hal ini. Mencoba layanan restart setelah * * * * * touch /tmp/cronworkstidak melakukan apa pun, namun ada RELOADdi cronlog.
НЛО
36

Path absolut harus digunakan untuk skrip:

Misalnya, /bin/grepharus digunakan daripada 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 sulit, karena perintah yang sama akan berfungsi ketika dijalankan dari shell. Alasannya adalah bahwa crontidak memiliki PATHvariabel lingkungan yang sama dengan pengguna.

Adam Matan
sumber
3
lihat jawaban geirha, Anda dapat (harus) mendefinisikan PATH cron
Capi Etheriel
9
Bzzt. Anda TIDAK perlu mendefinisikan PATH - menggunakan path absolut adalah praktik terbaik di sini. "karena dapat dieksekusi mungkin di tempat lain di komputer lain" tidak benar "Saya ingin menjalankan program ini dengan tepat dan tidak ada orang lain yang menempatkan seseorang di jalur di depan program asli saya"
pbr
1
ya ini untuk saya, di luar cron saya bisa menjalankan perintah secara langsung, di dalam cron itu diperlukan /usr/bin/whateverpath lengkap
Anentropic
32

Jika 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

JMS
sumber
Inilah yang menyebabkan pekerjaan Cron saya gagal selama seminggu terakhir. Akhirnya tahu bahwa Kencan saya tidak memiliki karakter pelarian (backslash untuk orang lain yang mencari apa karakter pelarian itu). Yay!
Valien
25

Cron memanggil skrip yang tidak dapat dieksekusi.

Dengan menjalankan chmod +x /path/to/scripskrip menjadi executable dan harus menyelesaikan masalah ini.

jet
sumber
5
Itu tidak unik untuk cron, dan mudah dilacak dengan hanya mencoba mengeksekusi /path/to/scriptdari baris perintah.
Adam Matan
4
Jika Anda terbiasa untuk menjalankan script dengan . scriptnameatau sh scriptnameatau bash scriptname, maka ini menjadi cronmasalah -specific.
Eliah Kagan
24

Mungkin juga kata sandi pengguna telah kedaluwarsa. Bahkan kata sandi root dapat kedaluwarsa. Anda dapat tail -f /var/log/cron.logdan 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:

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

harus diedit ( sudo nano /etc/rsyslog.conf) dihapus komentarnya untuk:

cron.*                          /var/log/cron.log

Setelah itu, Anda harus memulai ulang rsyslog via

/etc/init.d/rsyslog restart

atau

service rsyslog restart 

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

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

untuk melihat pesan terkait cron.

tidak diketahui
sumber
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
18

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=:0suatu tempat.

andrew
sumber
aplay membutuhkan yang ini karena suatu alasan. terima kasih
IljaBek
* * * * * export DISPLAY=:0 && <command>
LoMaPh
15

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.

pengguna9521
sumber
Perhatikan bahwa jika Anda memiliki garis crontab yang diatur untuk mem-pipe output ke file yang belum ada, dan direktori untuk file tersebut adalah salah satu yang tidak dapat diakses oleh pengguna cron, maka baris tersebut tidak akan dieksekusi.
Evan Donovan
14

Izin tabel cron tidak aman

Tabel cron ditolak jika izinnya 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)

Masalahnya diselesaikan dengan

# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs
John Peterson
sumber
Pertama saya menemukan jawabannya sendiri dan kemudian saya menemukan jawaban Anda! Masih, terima kasih banyak! Dalam kasus saya, saya telah mengembalikan / mengembalikan beberapa crontab di / var / spool / cron / crontab melalui SVN yang mengubah izinnya!
alfonx
12

Skrip peka terhadap lokasi. Ini terkait dengan selalu menggunakan jalur absolut dalam skrip, tetapi tidak persis sama. Pekerjaan cron Anda mungkin perlu ke cddirektori 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

23 3 * * * cd / var / www / produksi / saat ini && / usr / bin / rake db: session_purge RAILS_ENV = produksi

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:

cd / var / www / produksi / saat ini
/ usr / bin / rake db: session_purge RAILS_ENV = produksi
pjmorse
sumber
1
Jika skrip yang dipanggil dari cron ditulis dalam bahasa yang ditafsirkan seperti PHP, Anda mungkin perlu mengatur direktori kerja di skrip itu sendiri. Misalnya, dalam PHP: chdir(dirname(__FILE__));
Evan Donovan
Baru saja tertangkap dengan yang satu ini: skrip dulu berada di root direktori home saya, tapi kemudian saya memindahkannya (dan memperbarui crontab) dan tidak tahu mengapa itu tidak berfungsi. Ternyata skrip menggunakan jalur relatif, dengan asumsi bahwa skrip tersebut relatif terhadap lokasi skrip tetapi sebenarnya relatif terhadap akar direktori home saya karena itu adalah direktori kerja yang digunakan cron, itulah sebabnya skrip bekerja ketika itu di root direktori home saya (karena direktori kerja skrip yang diharapkan dan itu berfungsi sebenarnya kebetulan bertepatan).
Micheal Johnson
11

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/crontabdan 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 foundketika Anda memindahkan perintah /etc/crontabatau file /etc/cron.dke dalam file crontab pengguna.

Sebaliknya, cron akan menghasilkan kesalahan seperti /usr/bin/restartxyz is not a valid usernameatau serupa ketika terjadi kebalikannya.

pbr
sumber
10

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:

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands

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':

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands
Aaron Peart
sumber
5
Mengapa ini menyebabkan kegagalan? Masalah penyangga?
Adam Matan
Setiap output atau kesalahan trriggred melalui pekerjaan cron adalah gooing untuk dikirim ke mailbox.So Anda kita tidak boleh lupa untuk peduli tentang kesalahan ini / output.We dapat mengarahkan mereka ke file atau / dev / null
Nischay
10

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 *atau 11 15 * * *. Hari dalam seminggu untuk pekerjaan setelah tengah malam juga menjadi bingung MF adalah 2-6setelah tengah malam, bukan 1-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/3dalam spesifikasi waktu juga dapat menyebabkan kegagalan. Ini adalah opsi yang sangat berguna tetapi tidak tersedia secara universal. Saya juga mengalami masalah dengan daftar seperti 1-5atau 1,3,5.

Menggunakan jalur yang tidak memenuhi syarat juga menyebabkan masalah. Path default biasanya /bin:/usr/binjadi 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 -ljika 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:

#! / usr / bin / crontab
# Muat ulang crontab ini
#
54 12 * * * $ {HOME} / bin / crontab

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.

BillThor
sumber
3
Ini mencakup tiga masalah terpisah. Bisakah mereka dipecah menjadi jawaban yang terpisah?
Eliah Kagan
9
Bisakah Anda menjelaskan bagaimana 30 23 * * * menterjemahkan ke 11:15?
JYelton
@JYelton Itu jelas salah, seharusnya 15 23 * * *. Diperbaiki sekarang.
Melebius
7

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:

24 Okt 07:51:00 mybox cron [29024]: [ID 731128 auth.notice] pam_unix_account: cron berusaha memvalidasi myuser akun yang dikunci dari host lokal
24 Okt 07:52:00 mybox cron [29063]: [ID 731128 auth.notice] pam_unix_account: cron berusaha memvalidasi myuser akun yang dikunci dari host lokal
24 Okt 07:53:00 mybox cron [29098]: [ID 731128 auth.notice] pam_unix_account: cron berusaha memvalidasi myuser akun terkunci dari host lokal
24 Okt 07:54:00 mybox cron [29527]: [ID 731128 auth.notice] pam_unix_account: cron berusaha memvalidasi myuser akun terkunci dari host lokal

Yang harus Anda lakukan adalah menjalankan:

# passwd -u <USERNAME>

sebagai root untuk membuka kunci akun, dan crontab akan bekerja lagi.

JohnGH
sumber
7

Jika Anda memiliki perintah seperti ini:

* * * * * /path/to/script >> /tmp/output

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:

* * * * * /path/to/script >> /tmp/output 2>&1

untuk melihat apakah ini membantu Anda menangkap masalah Anda.

Philluminati
sumber
3

=== 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

AlonL
sumber
3

Saya sedang menulis skrip instalasi shell yang membuat skrip lain untuk membersihkan data transaksi lama dari database. Sebagai bagian dari tugas itu harus mengkonfigurasi cronpekerjaan harian untuk dijalankan pada waktu yang sewenang-wenang, ketika beban basis data rendah.

Saya membuat file mycronjobdengan jadwal cron, nama pengguna & perintah dan menyalinnya ke /etc/cron.ddirektori. Dua gotcha saya:

  1. mycronjob file harus dimiliki oleh root untuk menjalankan
  2. Saya harus mengatur izin file ke 644 - 664 tidak akan berjalan.

Masalah izin akan muncul /var/log/syslogsebagai 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 merujuk ke /etc/crontabfile dan kemudian ke file yang saya tempatkan di bawah /etc/cront.d.

Izik Golan
sumber
2

Baris yang ditulis dengan cara crontab tidak mengerti. Itu harus ditulis dengan benar. Inilah CrontabHowTo .

Kangarooo
sumber
1
Bagaimana ini bisa di-debug?
Adam Matan
Meninjau log kesalahan cron adalah cara yang paling umum. IIRC 'crontab -e' melakukan parse sintaks setelah Anda juga mengedit file - tetapi itu mungkin tidak universal.
pbr
2

Cron daemon bisa berjalan, tetapi tidak benar-benar berfungsi. Coba mulai ulang cron:

sudo /etc/init.d/cron restart
Phil Dodd
sumber
3
Saya belum pernah melihat kasus ini dalam produksi. Bukan berarti itu belum terjadi - hanya saja saya belum melihatnya dalam 30 tahun saya telah menggunakan UNIX dan Linux. Cron sangat kuat.
pbr
1
Saya tidak yakin tetapi saya pikir ini benar-benar terjadi pada saya. Saya mencoba pidofcron dan tidak mendapatkan apa-apa. serviceSudah mencoba menggunakan utilitas dan katanya cron sudah berjalan. Hanya jalankan perintah ini dan jalankan pidoflagi dan saya mendapatkan hasil.
Colleen
2

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:

# m h dom mon dow command

* * */2  *   *  /some/shell/script

sedangkan / etc / crontab adalah:

# m h dom mon dow user   command

* * */2  *   *  jdoe   /some/shell/script

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 -edigunakan untuk menjalankan skrip dengan izin root, dengan yang sesuai chown username file_outputdalam skrip shell. Ceroboh, tetapi berhasil. IMHO, Pilihan yang lebih anggun adalah memasukkannya /etc/crontabdengan nama pengguna dinyatakan dan izin yang tepat, jadi file_outputpergi ke tempat dan pemilik yang tepat.

Mange
sumber
"Melakukannya (setidaknya di Ubuntu 10.10) memecah ketidakmampuan untuk membaca file dan juga mengeksekusi ....." Saya harus mengklarifikasi: / etc / crontab (secara default) memerlukan membaca DAN mengeksekusi izin, sedangkan Anda BISA jalankan "sudo crontab -e" untuk membuat cronjob yang mengesampingkan kebutuhan akan izin "w", dan masalah dengan ekstensi seperti ".sh". Saya belum punya waktu untuk memisahkan kode cron dan memeriksa mengapa ini bekerja, hanya detail yang saya perhatikan.
Kudis
2

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.

Kudis
sumber
1
Untuk program yang tidak memiliki mode hening, Anda dapat mengarahkan kembali hasilnya /dev/null. Sebagai contoh: some-command > /dev/nullIni 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, gunakan some-command &> /dev/null.
Eliah Kagan
Ya, itu adalah pikiran pertama saya ketika menulis naskah yang disebutkan sebelumnya. Saya lupa mengapa saya tidak menggunakan itu, mungkin beberapa perilaku non-standar yang menghindari solusi tersebut. Saya tahu bahwa mode verbose / interaktif adalah default pada beberapa perintah (Saya sedang melihat ANDA, scp!), Yang berarti Anda perlu repot-repot mengatakan output untuk kelancaran skrip shell.
Kudis
2

Meskipun Anda dapat mendefinisikan variabel lingkungan di crontable Anda, Anda tidak berada dalam skrip shell. Jadi konstruksi seperti berikut ini tidak akan berfungsi:

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

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:

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}
Alexandre
sumber
2

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 goaccessuntuk menganalisis file log server web. Ini TIDAK berfungsi di cron:

goaccess -a -f /var/log/nginx/access.log > output.html

dan goaccessmenunjukkan halaman bantuan alih-alih membuat laporan. Dalam shell ini dapat direproduksi dengan

goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null

Cara mengatasinya goaccessadalah membuatnya membaca log dari stdin alih-alih membaca dari file, jadi solusinya adalah mengubah entri crontab menjadi

cat /var/log/nginx/access.log | goaccess -a > output.html
Martijn de Milliano
sumber
2

Dalam kasus saya cron dan crontab memiliki pemilik berbeda.

TIDAK berfungsi, saya punya ini:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 

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:

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to [email protected].
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $
KiloOne
sumber
1
Meskipun didokumentasikan dengan baik, ini terlihat seperti titik spesifik Cygwin; apakah itu benar-benar milik askubuntu?
sxc731
2

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.

Dennis Parslow
sumber
2

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:

od -c /etc/cron.d/* | grep \r
Doug
sumber