[Server & Network General] Crontab: スクリプトを定期的に実行しログを残す
crontab の動作に関して確認してみました。
Contents
準備
レンタルサーバでやってみます。
つづきのような感じです。
こんなディレクトリを用意します。
- ~/sbin … cron で走らせるスクリプト
- ~/var/log … スクリプトの実行結果
- ~/var/com.example.www … mysqldumpファイル置き場
path を通すついでに、crontab -r の悲劇を起こさないよう、alias も作っておきます。
$ mkdir sbin
$ mkdir var
$ mkdir var/log
$ mkdir var/com.example.www
$ vim .zprofile
$ source ~/.zprofile
# Custom Path
export PATH=$PATH:$HOME/bin/:$HOME/sbin/
# cron
alias crontab='crontab -i'
crontab -e でこんな感じに設定します。
MAILTO='alert@example.com'
HOME='/home/myuser/'
LOG_DIR='/home/myuser/var/log'
15 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh
実行スクリプトはこのようにしてみました。
例外処理とかどう書けば良いかいまいち分かってない感じです。
#! /bin/zsh
bak_days=7
dest=/home/myuser/var/com.example.www
datetime=`date +%F_%T`
timestamp=`date +%Y%m%d`
limit=`date "-d $bak_days days ago" +%Y%m%d`
function backup {
bakfile=$dest/$timestamp.bak.sql.bz2
mysqldumpp --opt --all-databases | bzip2 -c > $bakfile
echo "$datetime Create: $bakfile"
}
function cleanup {
rmfile=$dest/$limit.bak.sql.bz2
rm -f $rmfile
echo "$datetime Delete: $rmfile"
}
backup
cleanup
/dev/null でログを捨てない
Cron Daemon からメール通知
上記のような準備をすると、ディフォルトの挙動として MAILTO に設定したメールアドレスへ結果ログを送ってくれます。
成功時
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron <root@example.com> /bin/zsh $HOME/sbin/blog_mysqldump.sh
2013-09-15_12:10:01 Create: /home/myuser/var/com.example.www/20130915.bak.sql.bz2
2013-09-15_12:10:01 Delete: /home/myuser/var/com.example.www/20130908.bak.sql.bz2
スクリプト内の echo が本文となっています。
ちなみに echo なしではメールが送信されませんでした。
失敗時
mysqldumpp と間違ったコマンドを書いてみました。
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron <root@example.com> /bin/zsh $HOME/sbin/blog_mysqldump.sh
backup:2: command not found: mysqldumpp
2013-09-15_12:10:01 Create: /home/myuser/var/com.example.www/20130915.bak.sql.bz2
2013-09-15_12:10:01 Delete: /home/myuser/var/com.example.www/20130908.bak.sql.bz2
function backup の 2行目のコマンドが見つからない、ということでしょうか。
ログファイルに残す
レンサバなので自前ログに残す方法で。
ほんとうはログローテションしないといけない。
*/10 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh >> $LOG_DIR/blog_mysqldump 2>&1
2>&1 について
成功時
$ tail -f ~/var/log/blog_mysqldump
2013-09-15_12:10:01 Create: /home/myuser/var/com.example.www/20130915.bak.sql.bz2
2013-09-15_12:10:01 Delete: /home/myuser/var/com.example.www/20130908.bak.sql.bz2
2013-09-15_12:20:01 Create: /home/myuser/var/com.example.www/20130915.bak.sql.bz2
2013-09-15_12:20:01 Delete: /home/myuser/var/com.example.www/20130908.bak.sql.bz2
失敗時
$ tail -f ~/var/log/blog_mysqldump
2013-09-15_12:10:01 Create: /home/myuser/var/com.example.www/20130915.bak.sql.bz2
2013-09-15_12:10:01 Delete: /home/myuser/var/com.example.www/20130908.bak.sql.bz2
backup:2: command not found: mysqldumpp
2013-09-15_12:20:01 Create: /home/myuser/var/com.example.www/20130915.bak.sql.bz2
2013-09-15_12:20:01 Delete: /home/myuser/var/com.example.www/20130908.bak.sql.bz2
メール通知&ログに残す
2>&1 | mail
pipe で mail コマンドを叩いてみます。
*/10 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh >> $LOG_DIR/blog_mysqldump 2>&1 | mail $MAILTO
メッセージとサブジェクトが空です。
成功したのか失敗したのか分かりません。
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron <root@example.com> /bin/zsh $HOME/sbin/blog_mysqldump.sh >> $LOG_DIR/blog_mysqldump 2>&1 | mail $MAILTO
No message, no subject; hope that's ok
1> /dev/null
標準出力を捨て、標準エラー出力をメールで送信する設定。
うまい書き方が分かりませんでした。これだとログには残らない。
*/10 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh 1> /dev/null
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron <root@example.com> /bin/zsh $HOME/sbin/blog_mysqldump.sh 1> /dev/null
backup:2: command not found: mysqldumpp
例外処理も含め、スクリプト内でできるようにすべきなのかもしれない。
また修行ですね。