Bagaimana saya bisa secara terprogram membuat pekerjaan cron baru?


129

Saya ingin dapat secara sistematis menambahkan pekerjaan cron baru, apa cara terbaik untuk melakukan ini?

Dari penelitian saya , sepertinya saya bisa membuang crontab saat ini dan kemudian menambahkan yang baru, menyalurkannya kembali ke crontab:

(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -

Apakah ada cara yang lebih baik?


2
Solusi Anda sepertinya bagus.
Craig S

Pada Solaris hanya menghapus tanda hubung untuk crontab terakhir. Anda dapat menambahkan grep untuk menghindari menambahkan garis yang sudah ada di sana.
lacroix1547


kurung kurawal bukannya kurung akan melakukannya tanpa memunculkan proses. Pastikan untuk menjaga ruang di sekitar kawat gigi, {...; }.
Jay Winston

Jawaban:


-25

Itu selalu bekerja dengan baik untuk saya.

Anda harus mempertimbangkan skrip yang sedikit lebih canggih yang dapat melakukan tiga hal.

  1. Tambahkan garis crontab; memastikan bahwa itu tidak ada. Menambahkan ketika sudah ada buruk.

  2. Hapus garis crontab. Mungkin hanya peringatan jika tidak ada.

  3. Kombinasi dari dua fitur di atas untuk menggantikan garis crontab.


78
Dia bertanya bagaimana dan Anda memberi tahu dia apa?
Cerin

1
Bagaimana jika pengguna belum memiliki crontab?
Maxim Egorushkin

132

Cara terbaik jika Anda menjalankan sebagai root, adalah dengan memasukkan file ke /etc/cron.d

jika Anda menggunakan manajer paket untuk mengemas perangkat lunak Anda, Anda dapat meletakkan file di direktori itu dan ditafsirkan seolah-olah itu adalah crontab, tetapi dengan bidang tambahan untuk nama pengguna, misalnya:

Nama file: /etc/cron.d/per_minute

Kandungan: * * * * * root /bin/sh /home/root/script.sh


5
Pastikan versi cron yang digunakan mendukung /etc/cron.d/. Kebanyakan distribusi Linux modern melakukannya.
sleske

8
Ini adalah solusi paling sederhana dan paling elegan. Tentu ketukan harus mengurai dan mengedit crontab yang ada dengan entri yang tidak terkait lainnya.
Cerin

13
Satu peringatan potensial untuk ini adalah frekuensi di mana cron mengambil tambahan baru ke folder ini (sekali per jam). Jika Anda mengharapkan pekerjaan Anda segera mulai berjalan, waspadalah.
JonathanK

6
@ JonathanK, apakah Anda kebetulan tahu apakah cron dapat diminta untuk memindai ulang /etc/cron.d/*? Sulit untuk mengetahui apakah sesuatu berfungsi jika seseorang harus menunggu satu jam untuk memeriksa!
halfer

4
bagaimana seharusnya perms diatur untuk file ini? chmod + x /etc/cron.d/per_minute?
giò

101

Solusi OP memiliki bug, mungkin memperbolehkan entri ditambahkan dua kali, gunakan di bawah untuk memperbaikinya.

(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -

5
Ini sebenarnya solusi yang lebih baik jika tidak dijelaskan. Ini memastikan perintah tidak ditambahkan dua kali ke crontab.
Bufke

2
Ini bukan perbaikan yang baik untuk masalah entri duplikat. Bagaimana jika baris lain ditambahkan ke crontab sementara itu?
hmn

6
Untuk memastikan keunikan, tepat sortsebelumnya uniq, misalnya:(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -
mway

6
Tidak perlu uniq. Gunakan -uopsi pada sort.
papiro

6
cara menghindari tidak ada crontab untuk pengguna saat saya pertama kali mengedit crontab.
wyx

23

Untuk menambahkan sesuatu ke cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -

Untuk menghapus ini dari cron

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh |  sort | uniq | crontab -

harapan akan membantu seseorang


Inilah yang saya cari, saya hanya ingin menambahkan ini: | grep -v '^ #' | untuk menyaring komentar
Tjunkie

2
Anda sebenarnya tidak perlu 2>&1 | grep -v "no crontab"karena ketika tidak ada crontab, garis output crontab: no crontab for...dikirim ke stderr. Tidak ada alasan untuk menangkap output itu, mengirimkannya ke stdout, dan kemudian menyaringnya menggunakan grep. Jika tujuan Anda adalah untuk menghindari melihat crontab: no crontab for...output Anda, maka gunakan 2> /dev/null | sort.....
matty


6

Cukup ubah perintah editor menjadi tee:

export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e

3
Waspadalah - ini menghapus semua entri yang ada.
Starfry

5

Dengan asumsi bahwa sudah ada entri di crontab Anda, perintah berikut harus bekerja relatif baik. Perhatikan bahwa $CMDvariabel hanya ada untuk dibaca. Menyortir sebelum memfilter duplikat penting, karena uniqhanya berfungsi pada baris yang berdekatan.

CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -

Jika saat ini Anda memiliki crontab kosong, Anda akan menerima kesalahan berikut untuk stderr:

no crontab for user

Jika Anda ingin menghindari ini, Anda dapat menambahkan sedikit kerumitan dan melakukan sesuatu seperti ini:

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -

5

Sebagian besar solusi di sini adalah dengan menambahkan baris ke crontab. Jika Anda membutuhkan lebih banyak kontrol, Anda ingin dapat mengontrol seluruh konten crontab.

Anda dapat menggunakan perpipaan untuk melakukan ini dengan cukup elegan.

Untuk sepenuhnya menulis ulang crontab, lakukan

echo "2 2 2 2 2 /bin/echo foobar" |crontab -

Ini harus mudah digabungkan dengan jawaban lain yang dijelaskan di sini seperti

crontab -l | <something> | tee |crontab -

Atau, jika Anda memiliki konten dalam file, itu bahkan lebih sederhana

cat <file> |crontab -

3

Berikut cara satu-liner lain, yang menghindari duplikat

(crontab -l 2>/dev/null | fgrep -v "*/1 *  *  *  * your_command"; echo "*/1 *  *  *  * your_command") | crontab -

Dan inilah cara untuk melakukan jawaban dan menghindari no crontab for userpesan dari JohnZ , atau jika Anda perlu beroperasi di set -eulingkungan tipe dan tidak bisa mendapatkan apa pun yang mengembalikan kegagalan (dalam hal ini 2>/dev/nullbagian ini opsional):

( (crontab -l 2>/dev/null || echo "")  ; echo "0 * * * * your_command") | sort -u - | crontab -

Atau jika Anda ingin membagi beberapa hal agar lebih mudah dibaca:

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
(echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab -

Atau secara opsional menghapus referensi ke perintah_Anda (mis: jika jadwal telah berubah, Anda hanya ingin itu pernah dicatat sekali). Dalam hal ini kita tidak lagi membutuhkan uniq(bonus tambahan, urutan penyisipan juga dipertahankan):

new_job="0 * * * * your_command"
preceding_cron_jobs=$(crontab -l || echo "")
preceding_cron_jobs=$(echo "$preceding_cron_jobs" | grep -v your_command )
(echo "$preceding_cron_jobs" ; echo "$new_job") | crontab -

2

man crontab juga berguna:

CRONTAB (1)

NAMA

   crontab - manipulate per-user crontabs (Dillon's Cron)

RINGKASAN

   crontab file [-u user] - replace crontab from file

   crontab - [-u user] - replace crontab from stdin

   crontab -l [user] - list crontab for user

3
Bagian yang mengatakan "ganti crontab dari stdin" sebenarnya setengah jawaban :-)
Grodriguez

2

Menambah jawaban JohnZ, inilah sintaks untuk menjadwalkan sebagai root jika Anda seorang sudoer:

(sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | sudo crontab -

1
function cronjob_exists($command){

    $cronjob_exists=false;

    exec('crontab -l', $crontab);


    if(isset($crontab)&&is_array($crontab)){

        $crontab = array_flip($crontab);

        if(isset($crontab[$command])){

            $cronjob_exists=true;

        }

    }
    return $cronjob_exists;
}

function append_cronjob($command){

    if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){

        //add job to crontab
        exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);


    }

    return $output;
}

    append_cronjob('* * * * * curl -s http://localhost/cron/test.php');

1

Ini akan memeriksa untuk memastikan bahwa perintah Anda belum ada sebelum menambahkannya.

crontab -l 2>/dev/null | grep -q '/path/to/script' || echo "5 * * * * /path/to/script" | crontab -

Bersulang.


0

Mem-pipkan stdout ke crontabtidak menginstal crontab baru untuk saya di macOS, jadi saya menemukan solusi ini sebagai gantinya, menggunakan teeeditor di sub shell:

(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)

0

Jika Anda ingin tugas dijalankan sebagai pengguna:

crontab -l | { cat; echo "@weekly what_you_want_to_execute"; } | crontab -

Jika Anda ingin tugas dijalankan dengan hak istimewa:

sudo crontab -l | { cat; echo "@weekly what_you_want_to_execute"; } | sudo crontab -

dan periksa tugas (dengan atau tanpa 'sudo'):

crontab -l | sed '/^$/d; /#/d'


-2

Anda juga dapat mengedit file teks tabel cron secara langsung, tetapi solusi Anda tampaknya dapat diterima.


1
Saya akan curiga dengan hal ini karena kekhawatiran akan kemungkinan penyuntingan bersamaan yang menyebabkan file korupsi. Menggunakan perintah crontab command-line harus menghindari masalah itu.
Craig S

Craig, tanpa riset lebih lanjut, saya tidak akan yakin bahwa versi baris perintahnya adalah atom dan ras-kondisi-aman. Mungkin "cukup aman".
tuomassalo

"Mengedit file secara langsung" tidak layak tanpa akses root (asalkan Anda dapat mengetahui di mana file crontab pengguna tinggal, dan bagaimana memastikan daemon cron menerima perubahan Anda dengan benar), dan "mengedit" secara terprogram sepertinya menjadi pertanyaannya ingin saran tentang di tempat pertama.
tripleee
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.