Cara mengatur pekerjaan root cron dengan benar

36

Saya mencoba mengatur pekerjaan root cron untuk menjalankan skrip Bash sebagai root, untuk dijalankan pada menit 7,37, setiap jam, setiap hari dalam sebulan, setiap bulan. Script ini terletak di /usr/bindan dinamai tunlrupdate.sh. Ini memperbarui DNS dari Tunlr.

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

Skrip Bash ini tersedia di sini .

Ketika dipanggil, skrip menulis apa yang terjadi di log yang berlokasi di /var/log/tunlr.log

Untuk menambahkan pekerjaan root cron ini, saya menggunakan standar untuk crontab root

sudo crontab -e

Dan memasukkan 2 baris ini di akhir. Saya berharap cron menjalankan skrip sebagai root.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

Perintah selanjutnya sudo crontab -lmengkonfirmasi bahwa tugas cron telah dimasukkan.

Saya melakukan reboot Ubuntu dan sedang memeriksa file log jika pekerjaan cron diluncurkan dengan benar. Namun tidak ada dalam logfile yang /var/log/tunlr.logberarti pekerjaan itu tidak pernah berhasil diluncurkan.

Saya memeriksa apakah saya menjalankan skrip dari baris perintah

sudo /usr/bin/tunlrupdate.sh

kemudian file log diperbarui sesuai.

Mengapa pekerjaan cron ini tidak berjalan sesuai rencana di sistem saya?

PEMBARUAN 1: Semua solusi yang diusulkan sejauh ini tidak berhasil. Saya berterima kasih kepada Olli untuk CLI untuk daftar log sistem sudo grep CRON /var/log/syslog. Namun saya memang mendapatkan kesalahan CRON

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

dengan PATH yang disarankan = penyisipan & penggunaan jalur absolut dari root untuk fungsi-fungsi dalam skrip atau tanpa solusi yang disarankan di sini. Saya masih mendapatkan kesalahan ini.

Setelah beberapa pencarian saya menemukan kesalahan dalam file /usr/lib/php5/maxlifetimeseperti yang dijelaskan di sini :Change #!/bin/sh -e --> #!/bin/sh -x

Kemudian daftar kesalahan log CRON di sistem saya

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

Saya masih belum mendapatkan eksekusi bash script. Kali ini tidak ada kesalahan yang ditampilkan di log. Untuk mendapatkan jaminan ini bukan isi skrip saya mengurangi skrip menjadi 3 baris berikut:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

Saya masih belum bisa menyelesaikan pekerjaan cron. Tidak ada yang tertulis dalam file log. Jadi, bahkan mungkin skrip kosong tidak akan berjalan di cron? Saya tidak mengerti. Saya tahu mencoba skrip direduksi menjadi 2 baris ini:

#!/bin/bash
exit 0

Dan masih log kesalahan yang sama. Script cron tidak melewati ...

Antonio
sumber
Jika Anda ingin menjadi cronjob "root", Anda harus menjadi root maka Anda mengetik crontab -e. Anda juga harus login sebagai root (konsol ketik "su root") dan kemudian crontab -e (sudo tidak diperlukan dalam kasus ini).
Wolfgang
Baik. Saya tidak melihat inti dari jawaban Anda? Mengetik $ sudo crontab -e melakukan pekerjaan seperti yang dilaporkan oleh $ sudo crontab -l, yaitu baris yang menggambarkan pekerjaan baru telah ditambahkan ke cron root. Sebagai per se pekerjaan itu tidak ada di cron pengguna misalnya $ crontab-l tidak menunjukkan pekerjaan cron ditambahkan di sini.
Antonio
@ WolfgangVogl dia menggunakan "sudo" yang berfungsi seperti yang diharapkan.
Alexis Wilke

Jawaban:

68

Jika Anda ingin menjalankan skrip sebagai pengguna biasa :

crontab -e

Dan tambahkan baris:

07,37 * * * * /usr/bin/tunlrupdate.sh

Jika Anda ingin menjalankan skrip Anda sebagai root :

sudo crontab -e

Dan tambahkan baris yang sama:

07,37 * * * * /usr/bin/tunlrupdate.sh
Guillaume
sumber
@NineCattoRules Jika Anda tidak menjatuhkan output, apa yang Anda lihat?
Angelo Fuchs
@AngeloFuchs komentar lama ... pasti saya mencoba perintah itu sebagai root ( sudo crontab -ebukan crontab -e). Atau sesuatu yang lain, tetap berfungsi
NineCattoRules
10

Nah, akhirnya solusi yang berhasil. Di syslog saya melihat yang berulang dan menarik:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

Kedengarannya seperti root tidak dikenali sebagai cmd. Karena saya sudah menggunakan cron root dengan menggunakan $ sudo /usr/bin/tunlrupdate.sh. Kemudian saya mencoba dengan skrip asli (dikoreksi karena kesalahan pada tanggal UNIX cmd:% m yang merupakan bulan digunakan untuk menit yaitu% M) berikut ini (yang menghilangkan root dari baris cron):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

Ini ternyata menjadi solusi terakhir. [Meskipun saya menemukan banyak literatur yang menyatakan garis yang salah dengan root pada baris cron. Itu adalah sebuah kesalahan].

Antonio
sumber
Poin bagus, Olli. Saya setuju dengan Anda tentang hal itu. Untuk referensi, pengguna crontab disimpan di / var / spool / cron / crontab / nama pengguna atau untuk root / var / spool / cron / crontab / root. Lihat halaman ini askubuntu.com/questions/216692/where-is-the-user-crontab-stored Folder yang sudah ada dan memberi nama pengguna.
Antonio
Nah, Anda tidak perlu informasi itu, karena Anda hanya perlu mengedit file crontab dengan crontabperintah (kecuali file crontab di bawah /etc).
Olli
1
@Antonio skor dengan bidang nama pengguna hanya digunakan di /etc/crontab(crontab seluruh sistem). Menggunakan sudo crontab -eAnda sedang bekerja dengan crontab root yang biasanya dapat ditemukan di/var/spool/cron/crontabs
Matijs
2

Satu "masalah" dengan cron adalah kurangnya variabel lingkungan (untuk alasan keamanan yang jelas ). Anda mungkin melewatkan PATH dan HOME. Anda dapat mendefinisikannya dalam skrip secara langsung atau dalam file crontab.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

Anda harus menguji sampai semua variabel yang diperlukan didefinisikan sebagaimana diminta oleh skrip.

Alexis Wilke
sumber
1
Inilah satu-satunya jawaban di sini yang benar-benar bekerja untuk saya. Saya menyalin pernyataan SHELL dan PATH dari /etc/crontabfile dan menempelkannya ke dalam sudo crontab -edan perintah dijalankan sebagai root tanpa masalah. Terima kasih!
Terrance
0

Pesan kesalahan Cron biasanya - secara default - dikirim melalui email. Anda dapat memeriksa apakah ada email untuk root sudo mail, atau dengan hanya memeriksa konten /var/mail/root, misalnya sudo less /var/mail/root.


Jika pesan email tidak membantu, periksa juga /var/log/syslog:

sudo grep CRON /var/log/syslog

Seperti yang dikatakan Alexis Wilke, cron memiliki mekanisme berbeda untuk mengatur variabel lingkungan.

Kebutuhan skrip Anda

PATH=/sbin:/bin:/usr/bin

ke crontab. HOMEseharusnya tidak perlu. Anda harus menggunakan jalur absolut dalam skrip Anda, misalnya /bin/datealih-alih date. Anda dapat menemukan jalur yang tepat untuk setiap perintah which command_name, misalnya

$ which date
/bin/date
Olli
sumber
Menjalankan grep CRON yang Anda sarankan di / var / log / syslog Saya mendapatkan menipu 11 Februari 14:37:01 Marius-PC CRON [7826]: (root) CMD (root /usr/bin/tunlrupdate.sh) 11 Februari 14: 37:01 Marius-PC CRON [7825]: (root) MAIL (mengirimkan 1 byte output; tetapi mendapat status 0x00ff, # 012) 11 Februari 14:39:01 Marius-PC CRON [7849]: (root) CMD ( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] && temukan / var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -type f -cmin + $ (/ usr / lib / php5 / maxlifetime)! -execdir fuser -s {} 2> / dev / null \; -delete) Jika saya menambahkan beberapa definisi untuk PATH di cron ini tidak akan mempengaruhi sistem saya $ PATH?
Antonio
Output itu mengatakan mencoba mengirim sesuatu tetapi gagal. Itu artinya, Anda tidak menerima pesan kesalahan itu /var/mail/root. Anda dapat memperbaikinya, atau cobaPATH=...
Olli
@Antonio, atau gunakan versi tambalan
Olli
Terima kasih. Saya tahu saya tidak mengonfigurasi sistem e-mail dan menyadari bahwa itu tidak berhasil. Saya sudah memodifikasi skrip untuk menggunakan path absolut untuk fungsi apa pun yang disebut. Hal terakhir adalah pertanyaan saya sebelumnya, definisi PATH dalam crontab tidak akan mengacaukan sistem saya $ variabel PATH?
Antonio
1
Sementara itu saya sibuk mengoreksi bug dalam format tanggal dari skrip asli. Itu menggunakan% m (yaitu untuk bulan BUKAN menit) alih-alih% M ...
Antonio
0

Anda dapat menambahkan baris ini dalam skrip Anda. Jadi setelah Anda memeriksa log cron dan menyetujui pekerjaan Anda dieksekusi, Anda bisa mendapatkan $ PATH dari crontab yang sama.

/bin/echo $PATH > /root/path.txt

Dan mungkin hal terbaik yang dapat Anda lakukan untuk mendiagnosis masalah dalam skrip cron adalah mendapatkan semua variabel lingkungan SO dengan perintah env di skrip Anda. Jadi tambahkan saja baris ini ke skrip Anda. Kemudian Anda bisa menganalisis hasilnyaallEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

Trik lain adalah mengarahkan output skrip ke suatu tempat. Menambahkan /root/log.log. Dengan cara ini semua output dari skrip akan dipertahankan/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

Anda juga dapat menjadwalkan skrip untuk menjalankan setiap menit untuk memfasilitasi tes dan pemeriksaan.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
Cassio Seffrin
sumber