安排每個月的最後一天
我從指令中閱讀了在每月最後一天安排腳本的說明:
注意:
精明的讀者可能想知道如何設置在每個月的最後一天執行的命令,因為您無法將 dayofmonth 值設置為涵蓋每個月。這個問題一直困擾著 Linux 和 Unix 程序員,並產生了很多不同的解決方案。一種常用的方法是添加一個 if-then 語句,該語句使用 date 命令檢查明天的日期是否為 01:
00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1
這將在每天中午 12 點檢查它是否是該月的最後一天,如果是,則 cron 執行該命令。
如何
[
date +%d -d tomorrow= 01 ]
工作?陳述是否正確
then; command1
?
抽象的
正確的程式碼應該是:
#!/bin/sh [ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1 [ "$(date -d tomorrow +'%d')" = 01 ] || exit 0 exec "$@"
呼叫此腳本
end_of_month.sh
,cron 中的呼叫很簡單:00 12 28-31 * * /path/to/script/end_of_month.sh command
end_of_month
這將僅在 28、29、30 和 31 天執行腳本(內部將檢查該天是否為該月的最後一天)。無需在任何其他日期檢查月末。舊帖。
這是 Richard Blum,Christine Bresnahan pp 442,第三版,John Wiley & Sons ©2015 所著的“Linux 命令行和 Shell 腳本聖經”一書中的引述。
是的,這就是它所說的,但這是錯誤/不完整的:
- 缺少一個結束
fi
。[
和以下之間需要空格```。- 強烈建議使用 $(…) 而不是
…
.- 重要的是在擴展周圍使用引號,例如
"$(…)"
;
後面還有一個then
我怎麼知道?(好吧,憑經驗☺)但你可以試試Shellcheck。粘貼書中的程式碼(在星號之後),它會向您顯示上面列出的錯誤以及“缺少的 shebang”。Shellcheck 中沒有任何錯誤的腳本是這樣的:
#!/bin/sh if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
該站點有效,因為編寫的是“外殼程式碼”。這是一種適用於許多 shell 的語法。
shellcheck 沒有提到的一些問題是:
- 假設 date 命令是 GNU date 版本。帶有
-d
接受tomorrow
作為值的選項的選項(busybox 有一個 -d 選項,但明天不理解,BSD 有一個-d
選項,但與時間的“顯示”無關)。- 最好在所有選項之後
date -d tomorrow +'%d'
設置格式。- cron 開始時間始終是本地時間,如果設置或取消設置 DST(夏令時),這可能會使一項作業比確切的天數早 1 小時或晚。
我們所做的是一個可以用 cron 呼叫的 shell 腳本。我們可以進一步修改腳本以接受要執行的程序或命令的參數,如下所示(最後是正確的程式碼):
#!/bin/sh [ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1 [ "$(date -d tomorrow +'%d')" = 01 ] || exit 0 exec "$@"
呼叫此腳本
end_of_month.sh
,cron 中的呼叫很簡單:00 12 28-31 * * /path/to/script/end_of_month.sh command
end_of_month
這將僅在 28、29、30 和 31 天執行腳本(內部將檢查該天是否為該月的最後一天)。無需在任何其他日期檢查月末。確保包含正確的路徑。cron 中的 PATH 不會(不太可能)與使用者 PATH 相同。
請注意,測試了****一個月末腳本(如下所示),它可以呼叫許多其他實用程序或腳本。
這也將避免 cron 使用完整命令行生成的額外問題:
%
即使用'
or引用, Cron 也會拆分命令行"
(此處僅\
適用)。這是 cron 作業失敗的常見方式。您可以
end_of_month.sh
通過使用 faketime 進行測試來測試腳本是否在某個日期正常工作(無需等到月底才發現它不起作用):$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...." Command will be executed....