このすみノート

Webエンジニアが技術や趣味を書くブログです。

crontabでdateコマンドを使った日付フォーマット(%)が動かなかった件

とある開発での話ですが、日次で動かしたい処理があったため、crontabで毎日17時の実行をセットしました。

crontabのイメージとしては、このようになります。

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
0 17 * * * * * root 実行したいプログラム > /tmp/ログ名-`date '+%Y%m%d%H%M%S'`.log

あくまで簡易的な試験実行だったため、あまり行儀は良くないですが実行ユーザーはroot、ログは手抜きで/tmp配下に実行日時を付けて保存することにしました。

ログが存在しないトラブルに遭遇する

17時に指定実行されたはずなので、時間が経った後にログを確認しようとしたところ、肝心のログが存在しません。

原因を探ってみたところ、フォーマットエラーで正常実行されなかったことが分かりました。

crontabではパーセント(%)をエスケープする必要がある

トラブルの原因は、crontab上に記載したdateコマンドです。 crontabでは、パーセント(%)をエスケープする必要があるとわかりました。

inexio.jp

エスケープの方法

パーセント(%)に対して、バックスラッシュでエスケープします。

# before
* * * * *   root echo "test" > /tmp/test-`date '+%Y%m%d%H%M%S'`.log

# after
* * * * *   root echo "test" > /tmp/test-`date '+\%Y\%m\%d\%H\%M\%S'`.log

softelさんの次の記事が参考になります。

www.softel.co.jp

なお、vimなどでシンタックスハイライトが効いていると、視覚的にも見分けることが可能です。 たとえば私のWSL2上では、エスケープされていない%Mによって、シンタックスハイライトが崩れている様子が見て取れます。

f:id:konosumi:20220109163709p:plain

さいごに

通常のコマンドライン実行では、パーセント(%)をエスケープしなくても正常実行されます。 そのため、実際にcrontabで動かすまで、失敗に気づきませんでした。

今回は実行後すぐ確認したため発覚が早かったですが、コマンドライン上で正常に動いたからといって、油断してはならないことを学びました。 教訓にしていきたいです。