crontabでのdateコマンド使用時には注意が必要

              ·

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