FreeBSDでcronにdateコマンドを含めたかったけどうまくいかない

1. はじめに

FreeBSD8.2-R amd64でcronにdateコマンドを含めたかったけどうまくいかない。
cronにdateコマンドを絡めた作業をさせたかった。具体的にはtarコマンドを用いてファイルのバックアップをとらせたかった。
このときファイル名にdateコマンドを用いて日付情報を付加しようと思った。でもうまく行かない。

とりあえず最初は思いついたとおりのコマンド、dateをバッククォートで囲んでそれを引数にtarをさせた。以下はバッククォートを利用したdateコマンドの例。

shell> grep date /etc/crontab
*       *       *       *       *       yousan  mail -s ` date '+%Y' ` [email protected] < hoge

上記のように書いたのだけれどうまく動かない。エラーログから察するに、 ‘mail -s `date’までは実行されている様子。
でもその後が続かない。

2. 意外にも解決方法がすぐにでてきたけれど。。。

さっくりググったら同じような症状がいっぱい出てきた。日本語の情報も数多くある。cron, dateというのはよくよく知られた問題のようだ。
標準のやり方ではうまく行かないみたい。またその対処方法も広く知られているらしい。
なんとwikipediaにまで対処方法が記載されていた。

よくあるミス

よくあるミスのひとつは、コマンド指定においてエスケープせずに「%」記号を使うことで、これはエスケープする必要がある。

# ミス:
1 2 3 4 5 touch ~/error_`date "+%Y%m%d"`.txt

この場合、デーモンからは以下のようなエラーメッセージがメール送信される:「/bin/sh: unexpected EOF while looking for `」

# エスケープしたもの:
1 2 3 4 5 touch ~/right_$(date +\%Y\%m\%d).txt
# 以下でも動作可能: シングルクオート
1 2 3 4 5 touch ~/error_$(date '+%Y%m%d').txt
# ダブルエスケープ版。以下のようなファイル名になる: ~/error_\2006\04\03.txt
1 2 3 4 5 touch ~/error_$(date '+\%Y\%m\%d').txt

crontab – Wikipedia

どうやらバッククォートの代わりに$を利用するといいらしい。
さっそくやってみた

3. $を使えばcronでdateがうまくいくはずが。。。

動かない。動かない。FreeBSDで$を使ってもコマンドに置換されない。
さっきの例だと変なメールが送られてくる。

下記はcrontabの記述

shell> grep mail /etc/crontab
* * * * * yousan  mail -s $(date '+%Y') [email protected] < ~yousan/tmp/hoge

送られてきたメール

From: [email protected]
To: [email protected]
 Subject: Cron <[email protected]&gt; mail -s $(date '+
X-Cron-Env: <SHELL=/bin/sh>
 X-Cron-Env: <PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin>
 X-Cron-Env: <[email protected]>
 X-Cron-Env: <HOME=/home/yousan>
X-Cron-Env: <LOGNAME=yousan>
X-Cron-Env: <USER=yousan>

Syntax error: Unterminated quoted string
 Syntax error: Error in command substitution

wikipediaとかその他諸々にあるような書き方をしてみたんだけれど動かない。FreeBSDは違うのかなぁ・・・、とか思っていろいろやってたらうまくいった。どうやらシングルクォートで括っても%はエスケープされない?(する必要がある?)ようだ。

下記の通りにするとうまくいった。

shell> grep mail /etc/crontab
 * * * * * yousan  mail -s $(date +\%Y) [email protected] < ~yousan/tmp/hoge

これでバックアップが全てちゃんととれるはず!

4. まとめ

FreeBSDのcrontabでdateコマンドなど、パーセントが含まれるコマンドを実行したいときには、シングルクォートで囲むだけではなくちゃんとバックスラッシュでクォートしてやる必要がある。

コメントを残す