[Server & Network General] Crontab: スクリプトを定期的に実行しログを残す
crontab の動作に関して確認してみました。
[markdown]
## 準備
レンタルサーバでやってみます。
つづきのような感じです。
> * [MySQL: コマンドをプロンプトなしでセキュアに利用するには | deadwood](https://www.d-wood.com/blog/2013/09/16_4641.html)
こんなディレクトリを用意します。
* ~/sbin … cron で走らせるスクリプト
* ~/var/log … スクリプトの実行結果
* ~/var/com.example.www … mysqldumpファイル置き場
path を通すついでに、crontab -r の悲劇を起こさないよう、alias も作っておきます。
“`prettyprinted
$ mkdir sbin
$ mkdir var
$ mkdir var/log
$ mkdir var/com.example.www
$ vim .zprofile
$ source ~/.zprofile
“`
“`bash:~/.zprofile
# Custom Path
export PATH=$PATH:$HOME/bin/:$HOME/sbin/
# cron
alias crontab=’crontab -i’
“`
crontab -e でこんな感じに設定します。
“`bash:crontab
MAILTO=’alert@example.com’
HOME=’/home/myuser/’
LOG_DIR=’/home/myuser/var/log’
15 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh
“`
実行スクリプトはこのようにしてみました。
例外処理とかどう書けば良いかいまいち分かってない感じです。
“`bash:~/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 で > /dev/null して椅子を投げられないための3つの方法 – 酒日記 はてな支店](http://d.hatena.ne.jp/sfujiwara/20120613/1339547638)
## Cron Daemon からメール通知
上記のような準備をすると、ディフォルトの挙動として MAILTO に設定したメールアドレスへ結果ログを送ってくれます。
### 成功時
“`prettyprinted
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron
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 と間違ったコマンドを書いてみました。
“`prettyprinted
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron
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行目のコマンドが見つからない、ということでしょうか。
## ログファイルに残す
レンサバなので自前ログに残す方法で。
ほんとうはログローテションしないといけない。
“`bash
*/10 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh >> $LOG_DIR/blog_mysqldump 2>&1
“`
2>&1 について
> * [cai.cs.shinshu-u.ac.jp/sugsi/Lecture/HowToUnix/2-1.html](http://cai.cs.shinshu-u.ac.jp/sugsi/Lecture/HowToUnix/2-1.html)
### 成功時
“`prettyprinted
$ 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
“`
### 失敗時
“`prettyprinted
$ 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 コマンドを叩いてみます。
“`bash
*/10 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh >> $LOG_DIR/blog_mysqldump 2>&1 | mail $MAILTO
“`
メッセージとサブジェクトが空です。
成功したのか失敗したのか分かりません。
“`prettyprinted
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron
No message, no subject; hope that’s ok
“`
### 1> /dev/null
標準出力を捨て、標準エラー出力をメールで送信する設定。
うまい書き方が分かりませんでした。これだとログには残らない。
“`bash
*/10 * * * * /bin/zsh $HOME/sbin/blog_mysqldump.sh 1> /dev/null
“`
“`prettyprinted
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron
backup:2: command not found: mysqldumpp
“`
> * [第30回 「cron のお勉強」](http://landisk.kororo.jp/diary/30_cron.php)
> * [crontabの設定メモ – ザリガニが見ていた…。](http://d.hatena.ne.jp/zariganitosh/20090303/1236127071)
例外処理も含め、スクリプト内でできるようにすべきなのかもしれない。
また修行ですね。
[/markdown]