ナクナイ

勉強用の備忘録

月末に cron を実行

月末のみ cron を実行したい!そんなときの crontab の書き方はこちら。この例では、毎月月末の朝10時に aiueo.pl を実行する記述。

0 10 * * * /usr/bin/test $( date -d '+1 day' +\%d ) -eq 1 && /home/tamulapin/aiueo.pl > /dev/null 2>&1

まず、ひとつずつ備忘。

test コマンド
test コマンドは、条件式の終了ステータス 0 か 1 のみを返します。

test 123 -eq 123 && ls

こうすれば ls は実行されます。

test 123 -eq 1234 && ls

こうすれば、ls は実行されません。


date コマンド
date コマンドは、時刻の表示や設定を行います。

$ date -d '+1 day'
2014年 12月 26日 金曜日 17:36:21 JST

こんな感じで、1日後の日付が返ってきます。

$ date -d '+1 day' +%d
26

これで、日付だけが返却されます。


改めて crontab を確認

0 10 * * * /usr/bin/test $( date -d '+1 day' +\%d ) -eq 1 && /home/tamulapin/aiueo.pl > /dev/null 2>&1

これはつまり、次の日が1日 (=今日が月末日) だったら aiueo.pl を実行する、ということになります。

ちなみに +%d を +\%d としているのは、エスケープなしで crontab に設定して実行したところ /var/log/cron に

crond[29480]: (tamulapin) CMD (/usr/bin/test $( date -d '+1 day' +)

みたいなエラーが出て、正しく実行されなかったため。

エラーを見ると、どうやら day 以降が切れてしまって crontab の記述が正しく認識されないことが原因みたい。ためしに手動で実行してみると、エスケープせずとも問題なく実行できました。

手動実行したシェルが zsh で crontab のシェルが bash だったので、そこらへんが原因なのかなと思い、ためしに自身のシェルを bash にして実行してみたけど、エスケープせずとも変わらず実行できたので、ちょっと謎。

おしまい