毎月末にスクリプトを予約するための指示を読みました。
メモ:
敏感な読者は、毎月最後の日にコマンドを実行するように設定する方法について疑問に思います。なぜなら、毎月対応する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
?
答え1
抽象的な
正しいコードは次のようになります。
#!/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
これは28、29、30、31日にのみスクリプトを実行しますend_of_month
(内部的にはその月の最後の日であることを確認します)。他の日付の月末を確認する必要はありません。
古い投稿。
これは、Richard BlumとChristine Bresnahanが書いた「Linux Command Line and Shell Scripting Bible」(442ページ、第3版、John Wiley&Sons©2015)の引用です。
はい、そう書いていますが、間違っているか不完全です。
- 結論的な発言がありません
fi
。 [
と後ろにはスペースが必要です`
。- これは強く代わりに$(...)を使用することをお勧めします
`…`
。 - 引用符を使用することが重要です。拡大する良い
"$(…)"
;
後で補足があります。then
私はどのように知っていますか? (まあ、経験上☺)しかし試してみることができます住宅検査。アスタリスクの後に本のコードを貼り付けると、「missing shebang」と一緒に上記のエラーが表示されます。 Shellcheckでエラーのないスクリプトは次のとおりです。
#!/bin/sh if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
書かれた内容が「シェルコード」なので、ウェブサイトが機能します。これは多くのシェルで動作する構文です。
Shellcheckで扱わないいくつかの問題は次のとおりです。
date コマンドが GNU 日付バージョンであると仮定します。値として
-d
受け入れられるオプションを持つオプションtomorrow
(busyboxには-dオプションがありますが、明日は理解できません。BSDには-d
オプションがありますが、時間の「表示」とは何の関係もありません)。フォーマットを設定するのが最善です。後ろにすべてのオプション
date -d tomorrow +'%d'
。クローン開始時間は常に現地時間であるため、夏時間(DST)が設定または設定されていない場合、ジョブは正確な日数より1時間早くまたは遅く開始することがあります。
私たちが完成したのは、cronで呼び出すことができるシェルスクリプトです。次のように実行されるプログラムまたはコマンドの引数を許可するようにスクリプトをさらに変更できます(最後の正しいコード)。
#!/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
これは28、29、30、31日にのみスクリプトを実行しますend_of_month
(内部的にはその月の最後の日であることを確認します)。他の日付の月末を確認する必要はありません。
正しいパスが含まれていることを確認してください。 cron内のPATHはユーザーのPATHと同じではありません。
あります。一つ月末スクリプトテスト済みです。(下図)は他の多くのユーティリティやスクリプトを呼び出すことができます。
また、コマンドライン全体を使用して、cronの作成に関連する追加の問題を回避できます。
%
Cronは、コマンドラインを使用または'
参照しても、すべてのコマンドラインでコマンドラインを分割します"
(ここではaのみ\
有効です)。これはクローン操作が失敗する一般的な方法です。
faketimeテストスクリプトを使用して、特定の日にスクリプトが動作しているかどうかをテストできますend_of_month.sh
(動作していないことを確認するために月末まで待つ必要はありません)。
$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....
答え2
構文エラーが修正され、コマンドが少し冗長に少し書き直されたと仮定します。
00 12 28-31 * * [ "$( date -d tomorrow +\%d )" != "01" ] || command1
明日の日付を2桁の形式で取得するにはdate +%d -d tomorrow
(GNUを使用していると仮定して)、このプログラムを実行してください。date
数字でない01
場合今日毎月最後の日ではありません。この場合、テストは成功command1
し、いいえ処刑される。ジョブはその月の最終日の正午に実行されます。
元のコマンド:
00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1
これにはいくつかの問題があります。
- その後にスペースはありません
[
。 ;
から直接then
。%
cronは作業仕様の特別な項目であり、エスケープする必要があります\%
(参照man 5 crontab
)。fi
一致する決勝戦はありませんでしたif
。
答え3
毎月最後の日を予約するには、以下を試してください0 0 15,L * *
。
答え4
あなたのクローンタブで
00 01 * * * [ $(date +\%d) -eq $(date \-d "-$(date +\%d) days month" +\%d) ] && /path/to/script.sh
上記は毎月末の午前1時に実行されます。