Pertanyaan Mengapa crontab saya tidak berfungsi, dan bagaimana saya bisa memecahkan masalah itu?


Ini adalah sebuah Pertanyaan Kanonis tentang menggunakan cron & crontab.

Anda telah diarahkan ke sini karena komunitas cukup yakin bahwa jawaban atas pertanyaan Anda dapat ditemukan di bawah ini. Jika pertanyaan Anda tidak dijawab di bawah ini maka jawabannya akan membantu Anda mengumpulkan informasi yang akan membantu masyarakat membantu Anda. Informasi ini harus diedit ke pertanyaan awal Anda.

Jawaban untuk 'Mengapa crontab saya tidak berfungsi, dan bagaimana saya bisa memecahkan masalah itu?'dapat dilihat di bawah ini. Ini alamat cron sistem dengan crontab yang disorot.


193
2017-11-17 04:51




Ini adalah penipuan besar Alasan mengapa crontab tidak berfungsi di AskUbuntu. - Dan Dascalescu


Jawaban:


Cara memperbaiki semua masalah / masalah terkait crontab Anda (Linux)


Ini adalah sebuah komunitas wiki, jika Anda melihat sesuatu yang salah dengan jawaban ini atau memiliki informasi tambahan, silakan edit.


Pertama, terminologi dasar:

  • cron (8) adalah daemon yang mengeksekusi perintah terjadwal.
  • crontab (1) adalah program yang digunakan untuk memodifikasi file pengguna crontab (5).
  • crontab (5) adalah per file pengguna yang berisi instruksi untuk cron (8).

Selanjutnya, edukasi tentang cron:

Setiap pengguna pada sistem mungkin memiliki file crontab mereka sendiri. Lokasi file root dan pengguna crontab tergantung pada sistem tetapi umumnya di bawah /var/spool/cron.

Ada sistem yang luas /etc/crontab file, yang /etc/cron.d direktori dapat berisi fragmen crontab yang juga dibaca dan ditindaklanjuti oleh cron. Beberapa distribusi Linux (misalnya, Red Hat) juga ada /etc/cron.{hourly,daily,weekly,monthly} yang merupakan direktori, skrip di dalamnya yang akan dijalankan setiap jam / hari / minggu / bulan, dengan hak akses root.

root dapat selalu menggunakan perintah crontab; pengguna biasa mungkin atau tidak dapat diberikan akses. Ketika Anda mengedit file crontab dengan perintah crontab -e dan menyimpannya, crond memeriksa untuk validitas dasar tetapi tidak menjamin file crontab Anda dengan benar terbentuk. Ada sebuah file bernama cron.deny yang akan menentukan pengguna mana yang tidak bisa menggunakan cron. Itu cron.deny lokasi file tergantung pada sistem dan dapat dihapus yang memungkinkan semua pengguna untuk menggunakan cron.

Jika komputer tidak dinyalakan atau crond daemon tidak berjalan, dan tanggal / waktu untuk menjalankan perintah telah berlalu, crond tidak akan mengejar dan menjalankan query yang lalu.

rincian crontab, bagaimana merumuskan sebuah perintah:

Perintah crontab diwakili oleh satu baris. Anda tidak dapat menggunakan \ untuk memperpanjang perintah melalui beberapa baris. Hash (#) tanda merupakan komentar yang berarti apa pun pada baris tersebut diabaikan oleh cron. Memimpin spasi kosong dan baris kosong diabaikan.

SANGAT hati-hati saat menggunakan persen (%) masuk ke perintah Anda. Kecuali mereka melarikan diri \% mereka diubah menjadi baris baru dan semuanya setelah yang pertama tidak melarikan diri % diteruskan ke perintah Anda pada stdin.

Ada dua format untuk file crontab:

  • Crontab pengguna

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  *   command to be executed
    
  • Lebar sistem /etc/crontab dan /etc/cron.d fragmen

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  * user-name  command to be executed
    

Perhatikan bahwa yang terakhir membutuhkan nama pengguna. Perintah akan dijalankan sebagai nama pengguna.

5 baris pertama dari garis mewakili waktu ketika perintah harus dijalankan. Anda dapat menggunakan nomor atau di mana nama hari / bulan yang berlaku dalam spesifikasi waktu.

  • Kolom dipisahkan oleh spasi atau tab.
  • Koma (,) digunakan untuk menentukan daftar misalnya 1,4,6,8 yang berarti berjalan pada 1,4,6,8.
  • Rentang ditentukan dengan tanda pisah (-) dan dapat digabungkan dengan daftar, mis. 1-3,9-12 yang berarti antara 1 dan 3 kemudian antara 9 dan 12.
  • Itu / karakter dapat digunakan untuk memperkenalkan langkah misalnya 2/5 yang berarti mulai dari 2 kemudian setiap 5 (2,7,12,17,22 ...). Mereka tidak membungkus melewati akhir.
  • Sebuah tanda bintang (*) dalam bidang menandakan seluruh rentang untuk bidang itu (mis. 0-59 untuk bidang menit).
  • Rentang dan langkah dapat digabungkan misalnya */2 menandakan mulai dari minimum untuk bidang yang relevan kemudian setiap 2 mis. 0 untuk menit (0,2 ... 58), 1 untuk bulan (1,3 ... 11), dll.

Perintah cron debug

Periksa suratnya! Secara default cron akan mengirimkan output apa pun dari perintah ke pengguna yang menjalankan perintah sebagai. Jika tidak ada output tidak akan ada surat. Jika Anda ingin cron mengirim email ke akun lain maka Anda dapat mengatur variabel lingkungan MAILTO dalam file crontab misalnya.

MAILTO=user@somehost.tld
1 2 * * * /path/to/your/command

Tangkap sendiri hasilnya

1 2 * * *  /path/to/your/command &>/tmp/mycommand.log

yang menangkap stdout dan stderr ke /tmp/mycommand.log

Lihatlah batang kayu; cron mencatat tindakannya melalui syslog, yang (tergantung pada pengaturan Anda) sering pergi ke /var/log/cron atau /var/log/syslog.

Jika diperlukan, Anda dapat memfilter laporan cron dengan mis.

grep CRON /var/log/syslog 

Sekarang kita telah membahas dasar-dasar cron, di mana file-file tersebut dan bagaimana menggunakannya mari kita lihat beberapa masalah umum.

Periksa apakah cron sedang berjalan

Jika cron tidak berjalan maka perintah Anda tidak akan dijadwalkan ...

ps -ef | grep cron | grep -v grep

harus memberimu sesuatu seperti itu

root    1224   1  0 Nov16 ?    00:00:03 cron

atau

root    2018   1  0 Nov14 ?    00:00:06 crond

Jika tidak memulai ulang

/sbin/service cron start

atau

/sbin/service crond start

Mungkin ada metode lain; gunakan apa yang disediakan distro Anda.

cron menjalankan perintah Anda di lingkungan yang terbatas.

Variabel lingkungan apa yang tersedia kemungkinan sangat terbatas. Biasanya, Anda hanya akan mendapatkan beberapa variabel yang ditentukan, seperti $LOGNAME, $HOME, dan $PATH.

Dari catatan khusus adalah PATH dibatasi untuk /bin:/usr/bin. Sebagian besar "skrip cron saya tidak berfungsi" masalah disebabkan oleh jalur terbatas ini. Jika perintah Anda berada di lokasi berbeda, Anda dapat menyelesaikannya dengan beberapa cara:

  1. Berikan jalur lengkap ke perintah Anda.

    1 2 * * * /path/to/your/command
    
  2. Berikan PATH yang sesuai dalam file crontab

    PATH=/usr:/usr/bin:/path/to/something/else
    1 2 * * * command 
    

Jika perintah Anda memerlukan variabel lingkungan lain, Anda dapat mendefinisikannya dalam file crontab juga.

cron menjalankan perintah Anda dengan cwd == $ HOME

Terlepas dari di mana program yang Anda laksanakan berada di filesystem, direktori kerja saat ini dari program ketika cron menjalankannya direktori home pengguna. Jika Anda mengakses file di program Anda, Anda harus mempertimbangkan hal ini jika Anda menggunakan jalur relatif, atau (sebaiknya) hanya menggunakan jalur yang sepenuhnya memenuhi syarat di mana saja, dan menyelamatkan semua orang dengan banyak kebingungan.

Perintah terakhir di crontab saya tidak berjalan

Cron umumnya mengharuskan perintah diakhiri dengan baris baru. Edit crontab Anda; pergi ke ujung baris yang berisi perintah terakhir dan masukkan baris baru (tekan enter).

Periksa format crontab

Anda tidak dapat menggunakan crontab yang diformat pengguna untuk / etc / crontab atau fragmen di /etc/cron.d dan sebaliknya. Pengguna yang diformat crontab tidak termasuk nama pengguna di posisi ke-6 berturut-turut, sementara sistem yang diformat crontab termasuk nama pengguna dan menjalankan perintah sebagai pengguna itu.

Saya meletakkan file di /etc/cron.{hourly,daily,weekly,monthly} dan tidak berjalan

  • Periksa bahwa nama file tidak memiliki ekstensi run-bagian
  • Pastikan file telah mengeksekusi izin.
  • Beri tahukan sistem apa yang harus digunakan saat menjalankan skrip Anda (mis., Masukkan #!/bin/sh di atas)

Cron date bugs terkait

Jika tanggal Anda baru-baru ini diubah oleh pengguna atau pembaruan sistem, zona waktu atau lainnya, maka crontab akan mulai berperilaku tidak teratur dan menunjukkan bug aneh, kadang bekerja, terkadang tidak. Ini adalah usaha crontab untuk mencoba "melakukan apa yang Anda inginkan" ketika waktu berubah keluar dari bawahnya. Bidang "menit" akan menjadi tidak efektif setelah jam berubah. Dalam skenario ini, hanya tanda bintang yang akan diterima. Restart cron dan coba lagi tanpa tersambung ke internet (jadi tanggal tidak memiliki kesempatan untuk me-reset ke salah satu server waktu).

Tanda persen, lagi

Untuk menekankan saran tentang tanda persen, berikut ini contoh apa yang dilakukan cron dengan mereka:

# cron entry
* * * * * cat >$HOME/cron.out%foo%bar%baz

akan membuat file ~ / cron.out yang berisi 3 baris

foo
bar
baz

Ini sangat mengganggu ketika menggunakan date perintah. Pastikan untuk menghindari tanda-tanda persen

* * * * * /path/to/command --day "$(date "+\%Y\%m\%d")"

273
2017-10-09 15:29



Mungkin ingin juga menyebutkan di bagian 'restricted env' yang LD_LIBRARY_PATH mungkin juga perlu memiliki direktori tambahan yang ditetapkan jika tugas cron Anda gagal karena tidak dapat menemukan pustaka bersama. - DavidJ
perhatikan bahwa Anda bahkan dapat menulis sesuatu seperti ini: 35,5-23 / 2 * * * do_something, bukan 35,1,5,7,9, .. * * * Selain itu, crontab.guru menerjemahkan entri yang Anda buat ke bahasa manusia. - Dennis Nolte
Hasil tangkapan tidak bekerja untuk saya, mungkin karena sh shell. Saya pikir ini lebih portabel: ... /path/to/your/command >/tmp/mycommand.log 2>&1 - chus
ini berhasil untuk saya: sudo apt-get install postfix - jmunsch
Apakah tugas cron juga tergantung pada seberapa berat file itu? Karena saya berlari dunia halo sederhana dengan python dengan cron, itu berhasil. Tapi kode kedua saya agak berat dan biasanya dijalankan tetapi dengan cron itu tidak memberikan output apa pun ke dalam file. - Devendra Bhat


Jika cronjobs Anda berhenti berfungsi, periksa bahwa kata sandi Anda belum kedaluwarsa., Karena begitu selesai, semua tugas cron berhenti.
Akan ada pesan masuk /var/log/messages mirip dengan yang di bawah ini yang menunjukkan masalah dengan mengautentikasi pengguna:

(username) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)


18
2018-02-04 20:29



Baru saja ini juga (file pesan kesalahan / var / log / syslog untuk saya). Dalam kasus saya sebuah kotak DigitalOcean yang, pada saat membuat, mereka mereset kata sandi root (opsional) ke yang lain, dan tampaknya sampai Anda masuk ke sana dan mengubahnya, semua tugas cron tidak berjalan. Gelandangan. Memperbaiki sesuatu seperti itu sudo -u root passwd - rogerdpack


Debian Linux dan turunannya (Ubuntu, Mint, dll) memiliki beberapa kekhasan yang dapat menghalangi pekerjaan cron Anda dari mengeksekusi; khususnya, file dalam /etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly} harus:

  • dimiliki oleh root
  • hanya bisa ditulis oleh root
  • tidak dapat ditulis oleh kelompok atau pengguna lain
  • punya nama tanpa titik '.' atau karakter khusus lainnya tetapi '-' dan '_'.

Yang terakhir menyakitkan pengguna yang tidak curiga; khususnya skrip apa pun di salah satu folder ini bernama whatever.sh, mycron.py, testfile.pl, dll. akan tidak dieksekusi, selamanya.

Menurut pengalaman saya, titik khusus ini sejauh ini merupakan alasan paling sering untuk cronjob non-eksekusi pada Debian dan turunannya.

Lihat man cron untuk lebih jelasnya, jika perlu.


15
2017-11-17 14:37





Jadwal yang tidak biasa dan tidak teratur

Cron adalah semua hal yang dianggap sebagai penjadwal yang sangat mendasar dan sintaksnya tidak mudah memungkinkan administrator untuk merumuskan jadwal yang sedikit lebih jarang.

Pertimbangkan pekerjaan berikut yang biasanya akan dijelaskan "menjalankan command setiap 5 menit ":

*/5 * * * * /path/to/your/command

melawan:

*/7 * * * * /path/to/your/command

yang tidak selalu menjalankan command setiap 7 menit.

Ingat bahwa / karakter dapat digunakan untuk memperkenalkan langkah tetapi langkah tersebut tidak membungkus di luar bagian akhir seri, mis. */7 yang cocok setiap 7 menit dari menit 0-59  yaitu 0,7,14,21,28,35,42,49,56 namun antara satu jam dan berikutnya akan ada hanya 4 menit antar batch, setelah 00:56 seri baru dimulai 01:00, 01:07 dll. (dan batch tidak akan berjalan 01:03 , 01:10 , 01:17 dll.).


Apa yang harus dilakukan?

Buat beberapa batch

Daripada satu tugas cron, buat beberapa batch yang digabungkan menghasilkan jadwal yang diinginkan.

Misalnya untuk menjalankan batch setiap 40 menit (00:00, 00:40, 01:20, 02:00 dll) membuat dua batch, satu yang berjalan dua kali pada jam genap dan yang kedua yang hanya berjalan pada jam-jam ganjil:

# The following lines create a batch that runs every 40 minutes i.e.

# runs on   0:00, 0:40,        02:00, 02:40         04:00 etc to 22:40
0,40 */2 * * * /path/to/your/command

# runs on               01:20,               03:20,       etc to 23:20
20 1/2 * * * /path/to/your/command

# Combined: 0:00, 0:40, 01:20, 02:00, 02:40, 03:20, 04:00 etc.

Jalankan batch Anda lebih jarang 

Daripada menjalankan batch Anda setiap 7 menit, yang merupakan jadwal sulit untuk dipecah dalam beberapa batch, jalankan saja setiap 10 menit sebagai gantinya.

Jalankan batch Anda lebih sering 

Banyak jadwal aneh berevolusi karena runtime batch meningkat / berfluktuasi dan kemudian batch dijadwalkan dengan sedikit tambahan margin keamanan untuk mencegah berjalannya batch yang sama berikutnya dari tumpang tindih dan berjalan secara bersamaan.

Sebaliknya, berpikir secara berbeda dan cronjob yang akan gagal dengan anggun ketika sebelumnya belum selesai, tetapi yang akan berjalan sebaliknya. Lihat ini Q & A:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job --minutely

Pada catatan yang sama, Anda dapat membiarkan Anda merekam catatan waktu dari run terakhir yang berhasil dan pada awal pemeriksaan batch jika interval yang dikehendaki antara kumpulan sudah berlalu dan dieksekusi dan jika tidak keluar dengan lancar.

Dalam bash seven-minute-job akan terlihat seperti sesuatu seperti:

#!/bin/bash
# seven-minute-job
# This batch will only run when 420 seconds (7 min) have passed
# since the file /tmp/lastrun was either created or updated

if [ ! -f /tmp/lastrun ] ; then
    touch /tmp/lastrun
fi

if [ $(( $(date +%s) - $(date -r /tmp/lastrun +%s) )) -lt 420 ] ; then
    echo "The minimum interval of 7 minutes between successive batches hasn't passed yet."
    exit
fi

echo "Start running your batch"

date > /tmp/lastrun

Yang Anda dapat dengan aman (berusaha) untuk menjalankan setiap menit:

* * * * * /path/to/your/seven-minute-job

Jangan gunakan cron

Jika kebutuhan Anda kompleks, Anda mungkin mempertimbangkan untuk menggunakan produk yang lebih canggih yang dirancang untuk menjalankan jadwal yang kompleks (didistribusikan melalui beberapa server) dan yang mendukung pemicu, ketergantungan pekerjaan, penanganan kesalahan, retries monitoring dll. Jargon industri adalah "perusahaan" penjadwalan pekerjaan dan / atau "otomatisasi beban kerja".


10
2017-10-23 04:45





Khusus PHP

Jika Anda memiliki beberapa tugas cron seperti:

php /bla/bla/something.php >> /var/logs/somelog-for-stdout.log

Dan jika ada kesalahan, mereka akan dikirim kepada Anda, tetapi mereka tidak - periksa ini.

PHP secara default tidak mengirim kesalahan ke STDOUT. @Lihat https://bugs.php.net/bug.php?id=22839

Untuk memperbaikinya, tambahkan cli`s php.ini atau di baris Anda (atau dalam bash wrapper Anda untuk PHP) ini:

  • --define display_startup_errors = 1
  • --define display_errors = 'stderr'

Pengaturan pertama akan memungkinkan Anda untuk memiliki fatals seperti 'Memory oops' dan 2nd - untuk mengarahkan mereka semua ke STDERR. Hanya setelah Anda dapat tidur nyenyak karena semua akan dikirim ke email root Anda, bukan hanya login.


8



Laporan kesalahan itu ditutup kembali pada tahun 2007 dengan status patch yang ditambahkan ke cabang PHP 5.2+. Apakah Anda yakin ini diperlukan? Saya baru mencoba PHP 5.4 dan tampaknya berfungsi dengan baik. (Ini masih diperlukan untuk PHP 4 sekalipun). - Xeoncross
@Xeoncross lihat tanggal jawaban :) - gaRex
Ya, itulah yang membingungkan saya sejak Anda menjawab pada tahun 2013 dan tiket kembali pada '07. - Xeoncross