Abstrak
Kode yang benar adalah:
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
Panggil skrip ini end_of_month.sh
dan panggilan dalam cron sederhana:
00 12 28-31 * * /path/to/script/end_of_month.sh command
Itu akan menjalankan skrip end_of_month
(yang secara internal akan memeriksa bahwa hari itu adalah hari terakhir dalam sebulan) hanya pada hari ke 28, 29, 30 dan 31. Tidak perlu memeriksa akhir bulan pada hari lain.
Posting lama.
Itu adalah kutipan dari buku "Linux Command Line dan Shell Scripting Bible" oleh Richard Blum, Christine Bresnahan hlm 442, Edisi Ketiga, John Wiley & Sons © 2015.
Ya, begitulah katanya, tapi itu salah / tidak lengkap:
- Tidak ada penutup
fi
.
- Membutuhkan ruang antara
[
dan berikut ini `
.
- Hal ini sangat dianjurkan untuk menggunakan $ (...) bukan
`…`
.
- Penting bahwa Anda menggunakan tanda kutip di sekitar ekspansi seperti
"$(…)"
- Ada tambahan
;
sesudahnyathen
Bagaimana aku tahu? (yah, berdasarkan pengalaman ☺) tetapi Anda dapat mencoba Shellcheck . Tempel kode dari buku (setelah tanda bintang) dan itu akan menunjukkan kepada Anda kesalahan yang tercantum di atas ditambah "hilang shebang". Script tanpa kesalahan di Shellcheck adalah ini:
#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
Situs itu berfungsi karena apa yang ditulis adalah "kode shell". Itu adalah sintaks yang bekerja di banyak shell.
Beberapa masalah yang tidak disebutkan shellcheck adalah:
Diasumsikan bahwa perintah tanggal adalah versi tanggal GNU. Yang dengan -d
opsi yang menerima tomorrow
sebagai nilai (busybox memiliki opsi -d tetapi tidak mengerti besok dan BSD memiliki -d
pilihan tetapi tidak terkait dengan "tampilan" waktu).
Lebih baik mengatur format setelah semua opsi date -d tomorrow +'%d'
.
Waktu mulai cron selalu dalam waktu lokal, yang dapat membuat satu pekerjaan dimulai 1 jam lebih awal dari hari yang tepat dihitung jika DST (waktu musim panas) ditetapkan atau tidak disetel.
Apa yang kami lakukan adalah skrip shell yang bisa disebut dengan cron. Kami selanjutnya dapat memodifikasi skrip untuk menerima argumen dari program atau perintah untuk dieksekusi, seperti ini (akhirnya, kode yang benar):
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
Panggil skrip ini end_of_month.sh
dan panggilan dalam cron sederhana:
00 12 28-31 * * /path/to/script/end_of_month.sh command
Itu akan menjalankan skrip end_of_month
(yang secara internal akan memeriksa bahwa hari itu adalah hari terakhir dalam sebulan) hanya pada hari ke 28, 29, 30 dan 31. Tidak perlu memeriksa akhir bulan pada hari lain.
Pastikan jalur yang benar disertakan. PATH di dalam cron tidak akan (tidak mungkin) sama dengan PATH pengguna.
Perhatikan bahwa ada satu skrip akhir bulan yang diuji (seperti ditunjukkan di bawah) yang dapat memanggil banyak utilitas atau skrip lain.
Ini juga akan menghindari masalah tambahan yang dihasilkan cron dengan baris perintah penuh:
- Cron membagi baris perintah pada setiap
%
bahkan jika dikutip dengan '
atau "
(hanya \
berfungsi di sini). Itu adalah cara umum di mana pekerjaan cron gagal.
Anda dapat menguji apakah end_of_month.sh
skrip bekerja dengan benar pada tanggal tertentu (tanpa menunggu hingga akhir bulan untuk menemukan itu tidak berfungsi) dengan mengujinya dengan faketime:
$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....