Shell - crontabでのdateコマンド使用時には注意が必要
tips crontab · shell
crontab内で date
コマンド のフォーマット指定を行う場合は、 パーセント文字 %
のエスケープが必要との学びを得た 📝
経緯
以下の要件を満たすために、処理対象の日付を引数で受け取るバッチを作成し、実行を crontab にて記載した。
要件:
毎日 01:00 に起動し、前日のデータを対象に XXXXX を行う
crontab:
0 1 * * * /user/local/bin/awesome-cmd -d `date -v -1d +"%Y%m%d"`
しかし、上記指定はうまく行かず、以下のエラーが発生した旨メール通知がくる。
unexpected EOF while looking for matching ``'
そこでググって見ると、stackoverflow で似たような内容の質問を発見した。
質問: Date time format in UNIX crontab
回答: answer-30349069 by Jürgen Strobel
If you use a date format like date +"%d-%m-%Y_%H:%M" in your crontab you may need to escape the % characters with a backslash, like this: date +"%d-%m-%Y_%H:%M".
Many crons handle % specially by replacing them with newline and sending the following text as stdin to the command before it. See man 5 crontab for details.
要するに、 crontab 内では、 %
は改行に変換されるので、date
コマンドのフォーマット指定の場合には、エスケープが必要だよ。
とのこと。確かに、回答の通り +"%Y%m%d"
を +"\%Y\%m\%d"
に修正すると想定通りの動きになった。
crontab (修正後):
0 1 * * * /user/local/bin/awesome-cmd -d `date -v -1d +"\%Y\%m\%d"`
ほんのちょっと深掘り
回答に記載がある通り、 man 5 crontab
にはこの挙動についての説明が記載されていた。
$ man 5 crontab
(抜粋)
The ``sixth'' field (the rest of the line) specifies the command to be run. The entire command portion of the line, up to a new-
line or % character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the cronfile. Percent-signs
(%) in the command, unless escaped with backslash (\), will be changed into newline characters, and all data after the first %
will be sent to the command as standard input.
(意訳)
6番目のフィールドは実行対象のコマンドを指定します。改行または %文字 までのコマンド部分全体が、/bin/sh または cronfile のSHELL変数で
指定された シェル によって実行されます。バックスラッシュ(\) でエスケープされていない パーセント文字 (%) は改行文字に変換されます。
また、最初の %文字 以降の全てのデータは、標準入力を経由してコマンドに送られます。
また、EXAMPLE CRON FILE
には、パーセント文字 を使用する例として以下が記載されていた。
EXAMPLE CRON FILE
0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
crontab
でのコマンド指定は1行で書く必要があるので、改行を入力させるためにはこの仕様が必要ということだろうか。
ということで、新たな知見を得た。 (今更とか言わない)
おわり
comments powered by Disqus