概要
正しいコードは次のとおりです。
#!/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日目にのみスクリプトが実行されます(内部的にはその日が月の最終日であることを確認します)。月の終わりを他の日に確認する必要はありません。
古いポスト。
これは、リチャードブルムの著書「Linuxコマンドラインとシェルスクリプティングバイブル」、Christine Bresnahan pp 442、第3版、John Wiley&Sons©2015からの引用です。
はい、それはそれが言うことですが、それは間違っている/不完全です:
- クロージングがありません
fi
。
- 空間との間でニーズ
[
と以下`
。
- の代わりに$(…)を使用することを強くお勧めします
`…`
。
- 次のような展開を引用符で囲むことが重要です。
"$(…)"
- 追加があります
;
後は、then
どうやって知るの?(まあ、経験によると☺)しかし、あなたはShellcheckを試すことができます。本のコードを(アスタリスクの後に)貼り付けると、上記のエラーと「シバンがありません」が表示されます。Shellcheckでエラーのないスクリプトは次のとおりです。
#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
書かれているのは「シェルコード」だからです。これは多くのシェルで機能する構文です。
shellcheckが触れていないいくつかの問題は次のとおりです。
これは、dateコマンドがGNU日付バージョンであることを前提としています。1 -d
受け入れオプションtomorrow
(busyboxのは、-dオプションを持っていますが、明日を理解していないとBSDが持つ値として-d
オプションをが、時間の「表示」とは関係ありません)。
すべてのオプションの後にフォーマットを設定することをお勧めしますdate -d tomorrow +'%d'
。
cronの開始時刻は常に現地時間です。これにより、DST(夏時間)が設定または設定解除された場合、1つのジョブが正確な日数より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
これend_of_month
により、28日目、29日目、30日目、および31日目にのみスクリプトが実行されます(内部的にはその日が月の最終日であることを確認します)。月の終わりを他の日に確認する必要はありません。
正しいパスが含まれていることを確認してください。cron内のPATHは、ユーザーPATHと同じではありません(そうではありません)。
他の多くのユーティリティまたはスクリプトを呼び出す可能性のある、(以下に示すように)テストされた月末のスクリプトが1つあることに注意してください。
これにより、cronが完全なコマンドラインで生成する追加の問題も回避されます。
- Cron
%
は、'
またはで引用されている場合でも、コマンドラインを分割します"
(\
ここでは機能します)。これは、cronジョブが失敗する一般的な方法です。
end_of_month.sh
faketimeを使用してテストすることで、スクリプトが特定の日付で正しく機能するかどうかを確認できます(月末までに機能しないことを発見せずに)。
$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....