Öz
Doğru kod şöyle olmalıdır:
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
Bu komut dosyasını end_of_month.sh
çağırın ve cron'daki çağrı basitçe:
00 12 28-31 * * /path/to/script/end_of_month.sh command
Bu, senaryoyu end_of_month
(dahili olarak günün ayın son günü olup olmadığını kontrol edecektir) sadece 28, 29, 30 ve 31. günlerde çalıştıracaktır. Diğer günlerde ay sonunu kontrol etmeye gerek yoktur.
Eski yazı.
Richard Blum, Christine Bresnahan s. 442, Üçüncü Baskı, John Wiley & Sons © 2015 tarafından yazılan "Linux Komut Satırı ve Shell Scripting İncil" kitabından bir alıntıdır.
Evet, söylediği bu, ancak bu yanlış / eksik:
- Kapanış yok
fi
.
[
Aşağıdakiler ile aşağıdakiler arasında boşluk gerekir `
.
- Bunun yerine $ (…) kullanılması önemle tavsiye edilir
`…`
.
- Gibi genişletmelerde tırnak işaretleri kullanmanız önemlidir.
"$(…)"
;
Sonra bir ek varthen
Nasıl bilebilirim? (iyi, deneyime göre ☺) ama Shellcheck'i deneyebilirsiniz . Kodu kitaptan yapıştırın (yıldız işaretlerinden sonra) ve yukarıda listelenen hataları artı bir "eksik sapma" gösterecektir. Shellcheck'te hatasız bir komut dosyası şudur:
#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
Yazılan şey "kabuk kodu" olduğu için bu site çalışır. Bu, birçok kabukta çalışan bir sözdizimidir.
Shellcheck'in bahsetmediği bazı konular:
Date komutunun GNU tarih sürümü olduğu varsayılmaktadır. Bir değer olarak -d
kabul eden seçeneğe sahip olan tomorrow
(meşgul kutusunun -d seçeneği vardır, ancak yarını anlamamaktadır ve BSD'nin bir -d
seçeneği vardır, ancak zamanın "gösterimi" ile ilişkili değildir).
Tüm seçeneklerden sonra formatı ayarlamak daha iyidir date -d tomorrow +'%d'
.
Cron başlangıç zamanı her zaman yerel saattedir ve DST (gün ışığından yararlanma saati) ayarlanmış veya ayarlanmamışsa, bir işin tam gün sayımından 1 saat önce başlamasını sağlayabilir.
Yaptığımız şey cron ile çağrılabilecek bir kabuk betiğidir. Komut dosyasını, programın veya yürütülecek komutun argümanlarını kabul edecek şekilde, örneğin şu şekilde değiştirebiliriz (son olarak, doğru kod):
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
Bu komut dosyasını end_of_month.sh
çağırın ve cron'daki çağrı basitçe:
00 12 28-31 * * /path/to/script/end_of_month.sh command
Bu, senaryoyu end_of_month
(dahili olarak günün ayın son günü olup olmadığını kontrol edecektir) sadece 28, 29, 30 ve 31. günlerde çalıştıracaktır. Diğer günlerde ay sonunu kontrol etmeye gerek yoktur.
Doğru yolun dahil edildiğinden emin olun. Cron içindeki PATH, (PATH) kullanıcı PATH'si ile aynı olmayacaktır (büyük olasılıkla).
Not olduğunu bir ay script sonu test (aşağıda belirtildiği gibi) birçok araç veya komut dosyalarını diyebiliriz söyledi.
Bu, cron'un tam komut satırıyla oluşturduğu ek sorunu da önler:
- Cron
%
, '
veya ile belirtilen bile olsa komut satırını böler "
(yalnızca \
burada çalışır). Bu, cron işlerinin başarısız olduğu yaygın bir yoldur.
Test edebilirsiniz end_of_month.sh
komut faketime ile test ederek (bu işi yapmaz keşfetmeye ay sonuna kadar beklemeden) bazı tarihte düzgün çalışır:
$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....