Jalankan skrip melalui cron setiap minggu

12

Saya telah melakukan sedikit riset tentang bagaimana melakukan ini, dan saya melihat tidak ada cara langsung dalam cron untuk menjalankan pekerjaan, katakanlah, setiap Kamis.

Saat ini, saya condong ke arah membuat skrip yang hanya akan berjalan setiap minggu, dan akan menyentuh file "flag" saat dijalankan, dan jika dijalankan dan file tersebut sudah ada, untuk menghapus file (dan tidak melakukan aksi dwi-mingguan).

Pertanyaan saya adalah, apakah ada cara lain yang lebih elegan atau lebih sederhana untuk mencapai tujuan ini dari skrip aksi bash yang dijalankan setiap minggu secara otomatis?

Terima kasih!

dmkmills
sumber
1
Alih-alih file bendera, Anda bisa menggunakan angka minggu ISO. (Misalnya strftime's% V.)
@Roger: Saya kira maksud Anda dalam kondisi dalam skrip.
Dijeda sampai pemberitahuan lebih lanjut.
@ Dennis: Tidak harus (mis. Lihat bagaimana jawaban saya memeriksa di luar skrip), tetapi poin utama saya adalah itu akan jauh lebih sederhana dan tidak memerlukan keadaan dalam sistem file. Namun, saya menyadari itu memiliki kelemahan yang sama dengan memeriksa hari dalam sebulan: beberapa tahun memiliki 53 minggu dan beberapa memiliki 52.

Jawaban:

11
0 0 * * Thu bash -c '(($(date +\%s) / 86400 \% 14))' && your-script

Saya menggunakan bash untuk melakukan matematika karena saya malas; alihkan itu ke apa pun yang Anda suka. Saya memanfaatkan 1 Januari 1970 sebagai hari Kamis; untuk hari-hari lain dalam seminggu Anda harus menerapkan offset. Cron membutuhkan persen tanda lolos.

Pemeriksaan cepat:

function check {
  when=$(date --date="$1 $(($RANDOM % 24)):$(($RANDOM % 60))" --utc)
  echo -n "$when: "
  (($(date +%s --date="$when") / 86400 % 14)) && echo run || echo skip
}

for start in "2010-12-02" "2011-12-01"; do
  for x in $(seq 0 12); do
    check "$start + $(($x * 7)) days"
  done
  echo
done

Catatan Saya telah memilih waktu acak untuk menunjukkan ini akan bekerja jika dijalankan kapan saja pada hari Kamis, dan memilih tanggal yang melewati batas tahun ditambah bulan dengan 4 dan 5 Kamis.

Keluaran:

Thu Dec  2 06:19:00 UTC 2010: run
Thu Dec  9 23:04:00 UTC 2010: skip
Thu Dec 16 05:37:00 UTC 2010: run
Thu Dec 23 12:49:00 UTC 2010: skip
Thu Dec 30 03:59:00 UTC 2010: run
Thu Jan  6 11:29:00 UTC 2011: skip
Thu Jan 13 13:23:00 UTC 2011: run
Thu Jan 20 20:33:00 UTC 2011: skip
Thu Jan 27 16:48:00 UTC 2011: run
Thu Feb  3 17:43:00 UTC 2011: skip
Thu Feb 10 05:49:00 UTC 2011: run
Thu Feb 17 08:46:00 UTC 2011: skip
Thu Feb 24 06:50:00 UTC 2011: run

Thu Dec  1 21:40:00 UTC 2011: run
Thu Dec  8 23:24:00 UTC 2011: skip
Thu Dec 15 22:27:00 UTC 2011: run
Thu Dec 22 02:47:00 UTC 2011: skip
Thu Dec 29 12:44:00 UTC 2011: run
Thu Jan  5 17:59:00 UTC 2012: skip
Thu Jan 12 18:31:00 UTC 2012: run
Thu Jan 19 04:51:00 UTC 2012: skip
Thu Jan 26 08:02:00 UTC 2012: run
Thu Feb  2 17:37:00 UTC 2012: skip
Thu Feb  9 14:08:00 UTC 2012: run
Thu Feb 16 18:50:00 UTC 2012: skip
Thu Feb 23 15:52:00 UTC 2012: run

sumber
2
Detik sejak zamannya secara inheren dalam UTC, sementara cron berjalan dalam waktu lokal. Jika zona waktu sistem Anda bukan UTC, ini akan menyebabkan kebingungan. ("Mengapa tidak berjalan? Oh, sudah hari Jumat di UTC"). Keberadaan waktu musim panas membuat mengatasi hal ini menjadi jauh lebih sulit (walaupun bukan tidak mungkin, karena tanggal dapat memberitahu Anda offset UTC saat ini)
derobert
5

Salah satu cara mungkin menggunakan atutilitas jika Anda menjalankan Linux. Anda bisa meletakkan ini di akhir skrip Anda:

at X + 2 weeks -f myscript

di mana X adalah waktu Anda ingin menjalankan skrip Anda. Untuk menginisialisasi panggil saja atuntuk waktu Anda ingin menjalankannya pertama kali dan kemudian pernyataan di atas terus memperbarui panggilan terjadwal Anda.

gvkv
sumber
Jika ini akan menjadi solusi jangka panjang saya tidak akan merekomendasikan menjalankan ini meskipun pada saya akan membuat fungsi dalam skrip yang akan menentukan apakah perlu dijalankan
Paul
3

Jika Anda dapat menggunakan anacronpada sistem, semuanya akan jauh lebih sederhana. Untuk menggunakan anacronAnda harus menginstalnya dan Anda juga harus memiliki akses root. Itu tidak bekerja pada sistem yang lebih lama (yaitu RHEL 5.x), versi lama ancron ONLY berjalan saat boot up. Itu bekerja dengan sistem yang lebih baru (yaitu RHEL 6.x).

Dengan anacron, seseorang dapat menjadwalkan pekerjaan dengan cara yang lebih fleksibel, misalnya menjalankan pekerjaan X seminggu sekali. Juga anacronmenjalankan pekerjaan saat komputer tersedia, yaitu Anda tidak perlu mempertimbangkan ketika sistem naik atau turun.

Untuk menjalankan skrip setiap minggu, Anda harus menambahkan baris yang mirip dengan mengikuti ke / etc / anacrontab:

14 5 myScript script.sh

Lihatlah halaman manual untuk detailnya.

meminimalkan
sumber
Penggunaan anacronjelas merupakan solusi IMO terbersih (kecuali jika ada beberapa konsekuensi yang tidak diinginkan bagi sebagian orang).
JanC
0

Saya tidak yakin apakah ada cara yang lebih elegan untuk mendefinisikan setiap minggu, tetapi ini mungkin cocok untuk Anda.

00 06 1-7,15-21 * * test `date +\%a` = Thu && /path/to/script

Ini akan meluncurkan skrip pada pukul 6 pagi pada hari Kamis pertama dan ketiga setiap bulan.

pferate
sumber
2
Itu akan berakhir satu minggu jika ada satu bulan dengan 3 Kamis, meskipun.
David Z
1
Apakah ada satu bulan yang hanya memiliki 3 Kamis? Meskipun saya bisa melihatnya melewati seminggu jika ada 5 Kamis. Itu dapat diperbarui 1-7,15-21,29-31, tetapi kemudian akan berjalan kembali-ke-kembali jika ada kecocokan untuk set terakhir ...
pferate
1
Pada 3 Kamis, maksud Anda 3 Kamis bahwa skrip akan berjalan dan bukan 3 Kamis total? Saya mungkin salah baca pertama kali.
pferate
0

Saya akan menjalankannya setiap minggu, dan minta script memeriksa untuk melihat apakah nomor minggu adalah angka ganjil: jika ya keluar.

Ini akan membutuhkan lebih banyak pemikiran untuk bekerja dari Des hingga Jan.

Mungkin skrip mengatur file flag "last run sukses". Saat skrip diluncurkan, periksa file bendera yang terakhir diubah 14 hari yang lalu.

glenn jackman
sumber