Bagaimana cara membuat crontab melalui skrip

153

Saya perlu menambahkan pekerjaan cron melalui skrip yang saya jalankan untuk mengatur server. Saat ini saya menggunakan Ubuntu. Saya dapat menggunakan crontab -etetapi itu akan membuka editor untuk mengedit crontab saat ini. Saya ingin melakukan ini secara terprogram.

Apakah mungkin untuk melakukannya?

gaurav
sumber
Jika Anda ingin mengubah atau menghapus entri crontab, lihat solusi saya di bawah ini.
Brian Smith

Jawaban:

11

Pekerjaan Cron biasanya disimpan dalam file per pengguna di bawah /var/spool/cron

Hal paling sederhana yang dapat Anda lakukan mungkin hanya membuat file teks dengan pekerjaan yang dikonfigurasi, kemudian salin ke folder spool cron dan pastikan memiliki izin yang tepat (600).

Jason Stelzer
sumber
19
Memodifikasi file secara langsung di / var / spool / cron tidak disukai. Bahkan, jika Anda melihat file di sana, mereka biasanya akan berisi peringatan seperti "JANGAN EDIT FILE INI" sebagai baris pertama.
Jared
12
@ Jared Sementara saya cukup setuju dengan ide itu, mengatakan itu "disukai" tidak banyak membantu. Sebaliknya memberitahu yang lain file harus diedit, jika ada, atau menjelaskan risiko mengedit file secara manual. Saya berencana untuk membuat beberapa pekerjaan cron melalui baris perintah otomatis, dan jika mengedit file ini adalah satu-satunya pilihan, dan tanpa efek samping yang signifikan, saya tidak melihat mengapa saya tidak boleh menggunakannya.
Balmipour
47
Gulir ke bawah untuk jawaban yang sebenarnya.
John Red
1
Menurut pendapat saya, jawaban ini jauh lebih baik: stackoverflow.com/a/610860/2681752
galaux
2
Saya mengambil pendekatan ini dan menyesalinya. Pada RHEL, direktori / var / spool / cron tidak dapat dieksekusi dunia, sehingga pengguna tidak dapat melintasi direktori dan mengedit file mereka secara manual. Jika Anda membuat / var / spool / cron world dapat dieksekusi, sysadmin lokal Anda yang ramah akan marah kepada Anda, ditambah perubahan izin dapat ditimpa jika paket cronie pernah diinstal ulang atau diperbarui.
functionvoid
384

Berikut ini adalah satu-liner yang tidak menggunakan / memerlukan pekerjaan baru dalam file:

(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

Ini 2>/dev/nullpenting agar Anda tidak mendapatkan no crontab for usernamepesan yang dihasilkan oleh beberapa * nixes jika saat ini tidak ada entri crontab.

Joe Casadonte
sumber
14
Ini harus menjadi jawaban yang diterima. Hanya perlu cara sekarang untuk memeriksa apakah one-liner yang ingin saya tambahkan sudah ada atau tidak ...
ChrisPrime
7
... oh tunggu, inilah cara memeriksa apakah ada sesuatu di crontab pengguna saya sebelum saya menambahkannya dengan script: stackoverflow.com/a/14451184/3686125
ChrisPrime
1
jika skrip ini dimaksudkan sebagai perintah untuk diulangi dan memodifikasi tugas cron yang ada, bisa menyenangkan untuk mengganti baris yang ada di crontab. beberapa marker dapat digunakan untuk mengontrol tugas cron yang berbeda (control-marker-1, control-marker-2, dll ...): (crontab -l 2> / dev / null | grep -v control-marker-1; echo '* / 5 * * * * / path / ke / pekerjaan -dengan args # control-marker-1') | crontab -
chef
7
Saya menemukan bahwa ini menghapus entri crontab yang ada dan juga saya perlu menggunakan pengguna yang berbeda (root) jadi saya menggunakan yang berikut untuk mempertahankan entri yang ada: echo -e "$(sudo crontab -u root -l)\n* * * * * echo hello > /home/danny/temp.log 2>&1" | sudo crontab -u root -Semoga ini bisa membantu seseorang
Danny
60

Untuk crontab pengguna (termasuk root), Anda dapat melakukan sesuatu seperti:

crontab -l -u user | cat - filename | crontab -u user -

di mana file bernama "nama file" berisi item untuk ditambahkan. Anda juga bisa melakukan manipulasi teks menggunakan sedatau alat lain di tempat cat. Anda harus menggunakan crontabperintah daripada langsung memodifikasi file.

Operasi serupa adalah:

{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -

Jika Anda memodifikasi atau membuat crontab sistem, itu dapat dimanipulasi seperti yang Anda lakukan pada file teks biasa. Mereka disimpan dalam /etc/cron.d, /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthlydirektori dan file /etc/crontabdan /etc/anacrontab.

Dijeda sampai pemberitahuan lebih lanjut.
sumber
Tampak menjanjikan tetapi mencoba pendekatan kedua (dengan echo), saya mendapat "crontab: kesalahan penggunaan: nama file harus ditentukan untuk diganti." Halaman manual Cron menunjukkan sintaksis crontab [ -u user ] file, yaitu, dengan nama file wajib. Apakah ada beberapa trik untuk mendapatkannya agar menerima data yang disalurkan?
Mark Berry
1
@MarkBerry: Maaf tentang itu. Dalam sebuah pipa, tanda hubung harus digunakan untuk menunjukkan bahwa input berasal stdin. Saya akan memperbaiki jawaban saya.
Dijeda sampai pemberitahuan lebih lanjut.
29

Di Ubuntu dan banyak distro lainnya, Anda bisa memasukkan file ke /etc/cron.ddirektori yang berisi satu baris dengan entri crontab yang valid . Tidak perlu menambahkan baris ke file yang ada.

Jika Anda hanya perlu menjalankan sesuatu setiap hari, cukup masukkan file /etc/cron.daily. Demikian juga, Anda juga bisa drop file ke dalam /etc/cron.hourly, /etc/cron.monthlydan /etc/cron.weekly.

IvanGoneKrazy
sumber
5
Tetapi Anda harus menjadi root untuk melakukan ini.
Keith
17

Jawaban yang lebih sederhana untuk pertanyaan Anda adalah:

echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root

Anda dapat mengatur cronjobs pada server jarak jauh seperti di bawah ini:

#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
  do
  echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done

Di Linux, lokasi default crontabfile adalah /var/spool/cron/. Di sini Anda dapat menemukan crontabfile semua pengguna. Anda hanya perlu menambahkan entri cronjob Anda ke file masing-masing pengguna. Pada contoh di atas, file crontab pengguna root akan ditambahkan dengan cronjob untuk dijalankan /root/test.shsetiap hari pada pukul 1 pagi.

Ganesh Pathak
sumber
Itu akan /var/spool/cron/crontabs/rootdi Ubuntu.
Íhor Mé
17

File crontab hanyalah file teks dan karena itu dapat diperlakukan seperti file teks lainnya. Tujuan dari crontabperintah ini adalah membuat pengeditan file crontab lebih aman. Ketika diedit melalui perintah ini, file diperiksa untuk kesalahan dan hanya disimpan jika tidak ada.

crontab [path to file]dapat digunakan untuk menentukan crontab yang disimpan dalam file. Seperti crontab -e, ini hanya akan menginstal file jika bebas kesalahan.

Oleh karena itu, skrip dapat secara langsung menulis file tab cron, atau menulisnya ke file sementara dan memuatnya dengan crontab [path to temp file]perintah. Menulis secara langsung menghemat harus menulis file sementara, tetapi juga menghindari pemeriksaan keamanan.

cledoux
sumber
2
Untuk noobs seperti saya, perhatikan bahwa ini adalah crontab [path to file].. Ini jelas merupakan pilihan terbaik bagi saya, karena memungkinkan kode yang lebih mudah dibaca. Saya menggunakan crontab untuk melacak paket dan mengubah wallpaper desktop saya dengan status. Ketika saya tidak mengharapkan paket, tidak perlu memeriksa setiap jam. Itu sebabnya saya ingin skrip mengedit frekuensi cron secara otomatis.
Rasmus
1
@Rasmus Kedengarannya seperti naskah yang luar biasa, saya ingin sekali bisa mencuri. Adakah peluang berbagi melalui intisari atau serupa?
cledoux
8

(Saya tidak memiliki cukup reputasi untuk berkomentar, jadi saya menambahkan sebagai jawaban: silakan menambahkannya sebagai komentar di samping jawabannya)

One-liner Joe Casadonte sempurna, kecuali jika Anda menjalankannya set -e, yaitu jika skrip Anda disetel untuk gagal karena kesalahan, dan jika belum ada cronjobs. Jika demikian, one-liner TIDAK akan membuat cronjob, tetapi TIDAK akan menghentikan skrip. Kegagalan diam bisa sangat menyesatkan.

Alasannya adalah bahwa crontab -lkembali dengan 1kode kembali, menyebabkan perintah berikutnya (yang echo) tidak dieksekusi ... dengan demikian cronjob tidak dibuat. Tetapi karena mereka dieksekusi sebagai subproses (karena tanda kurung) mereka tidak menghentikan skrip.

(Menariknya, jika Anda menjalankan perintah yang sama lagi, itu akan bekerja: sekali Anda telah dieksekusi crontab -sekali, crontab -lmasih tidak menghasilkan apa-apa, tetapi tidak mengembalikan kesalahan lagi (Anda tidak mendapatkan no crontab for <user>pesan lagi). Jadi selanjutnya echodieksekusi dan crontab dibuat)

Dalam kasus apa pun, jika Anda menjalankannya set -e, garis harus:

(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -
Faria
sumber
Ya, ini bahkan lebih sempurna.
Yngve Sneen Lindal
7

Sebagai koreksi bagi mereka yang menyarankan crontab -l | crontab -: Ini tidak bekerja pada setiap sistem. Sebagai contoh, saya harus menambahkan pekerjaan ke root crontab pada lusinan server yang menjalankan SUSE versi lama (jangan tanya kenapa). SUSEs lama menambahkan baris komentar ke output crontab -l, menjadikan crontab -l | crontab -non-idempoten (Debian mengenali masalah ini di manual crontab dan menambal versi Vixie Cron untuk mengubah perilaku default crontab -l).

Untuk mengedit crontab secara terprogram pada sistem tempat crontab -lmenambahkan komentar, Anda dapat mencoba yang berikut:

EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -

EDITOR=catmemberitahu crontab untuk digunakan catsebagai editor (bukan vi standar yang biasa), yang tidak mengubah file, tetapi menyalinnya ke stdout. Ini mungkin masih gagal jika crontab -mengharapkan input dalam format yang berbeda dari crontab -eoutput apa . Jangan mencoba mengganti final crontab -dengan crontab -e- itu tidak akan berhasil.

pengguna2845840
sumber
4

Yah /etc/crontabhanya file ascii jadi yang paling sederhana adalah hanya

 echo "*/15 * * * *   root     date" >> /etc/crontab

yang akan menambah pekerjaan yang akan mengirimi Anda email setiap 15 menit. Sesuaikan dengan selera, dan uji melalui grepatau lainnya berarti apakah baris sudah ditambahkan untuk membuat skrip idempoten.

Di Ubuntu et al, Anda juga dapat meletakkan file /etc/cron.*yang lebih mudah dilakukan dan diuji --- plus Anda tidak mengacaukan file konfigurasi (sistem) seperti /etc/crontab.

Dirk Eddelbuettel
sumber
1
Saya pikir secara teknis tidak diperlukan untuk memonitor perubahan ke crontab, bahkan jika dalam kenyataannya sebagian besar implementasi melakukannya, jadi saya akan merekomendasikan panggilan ke crontab -e setelahnya untuk mendorongnya. crontab -e menghormati variabel EDITOR jika memori berfungsi, jadi mengaturnya ke / bin / true untuk saat ini seharusnya memaksa crontab untuk dibaca kembali.
Ulrich Schwarz
1
Benar namun pada setiap sistem Linux baru-baru crond ini memantau, dan tentu saja pada platform OP lain.
Dirk Eddelbuettel
Hanya jika Anda root dan ingin skrip dijalankan sebagai root. Itu mungkin tidak diinginkan dalam kasus OP.
Keith
Tidak demikian, saya punya banyak entri non-root di / etc / crontab. Anda 'hanya' perlu sudo untuk menambahkan file. Bagaimanapun, seperti yang saya nyatakan, ada juga /etc/cron.*/ tetapi Anda juga harus menjadi root untuk menulis di sana.
Dirk Eddelbuettel
2

Berikut adalah cara memodifikasi cron entri tanpa secara langsung mengedit file cron (yang disukai).

crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -

Jika Anda ingin menghapus entri cron, gunakan ini:

crontab -l -u <user> | sed '/find/d' | crontab -u <user> -

Saya menyadari ini bukan apa yang diminta gaurav, tetapi mengapa tidak memiliki semua solusi di satu tempat?

Brian Smith
sumber
1

Saya telah menulis alat penyebaran crontab dengan python: https://github.com/monklof/deploycron

pip install deploycron

Instal crontab Anda sangat mudah, ini akan menggabungkan crontab ke dalam sistem crontab yang ada.

from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")
monklof
sumber
1

Ini adalah pendekatan untuk menambahkan tugas cron secara bertahap:

  ssh USER_NAME@$PRODUCT_IP nohup "echo '*/2 * * * * ping -c2 PRODUCT_NAME.com >> /var/www/html/test.html' | crontab -u USER_NAME -"
Oleksii Kyslytsyn
sumber