[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 /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 と間違ったコマンドを書いてみました。

“`prettyprinted
From: root@example.com (Cron Daemon)
To: alert@example.com
Subject: Cron /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行目のコマンドが見つからない、ということでしょうか。

## ログファイルに残す

レンサバなので自前ログに残す方法で。
ほんとうはログローテションしないといけない。

“`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 /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

標準出力を捨て、標準エラー出力をメールで送信する設定。
うまい書き方が分かりませんでした。これだとログには残らない。

“`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 /bin/zsh $HOME/sbin/blog_mysqldump.sh 1> /dev/null
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]