## はじめに
`crontab` の書式は簡単ですが、いざシェルスクリプトを登録すると「手動では動くのにcronだと動かない」というハマりが頻発します。原因のほとんどはcron特有の最小環境変数、相対パスの罠、ログ未取得による失敗の見落としです。
本記事ではシェルスクリプトをcronから確実に実行するためのテンプレートと、運用で重要な排他制御、エラー通知の実装例を紹介します。
## 症状・背景
cronでスクリプト実行 が必要になる主な場面:
– 毎日のバックアップやログ整理
– 監視結果をSlackやメールに通知
– データベースの定期メンテナンス
– 一定間隔でAPIを叩くバッチ処理
## 手順・設定方法
### ステップ1: 実行できるスクリプトを用意
“`bash
# /usr/local/bin/backup.sh
sudo vi /usr/local/bin/backup.sh
“`
“`bash
#!/usr/bin/env bash
set -euo pipefail
# cronは最小PATHなので明示的に指定
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LOG=/var/log/myapp/backup.log
DATE=$(date +%Y%m%d)
echo “[$(date)] backup start” >> “$LOG”
tar czf /backup/db-${DATE}.tar.gz /var/lib/mysql
echo “[$(date)] backup done” >> “$LOG”
“`
“`bash
# 実行権限を付与
sudo chmod +x /usr/local/bin/backup.sh
“`
### ステップ2: cronに登録
“`bash
crontab -e
“`
“`cron
# 環境変数を上で宣言しておくと確実
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SHELL=/bin/bash
MAILTO=””
# 毎日3時に実行 (標準出力もログへ)
0 3 * * * /usr/local/bin/backup.sh >> /var/log/myapp/backup.log 2>&1
“`
### ステップ3: 排他制御と通知
“`bash
# 同時実行を防ぐ (flock)
0 * * * * flock -n /tmp/import.lock /usr/local/bin/import.sh >> /var/log/import.log 2>&1
# 失敗時のみメール通知 (chronicが便利)
0 3 * * * chronic /usr/local/bin/backup.sh
# 失敗時にSlack通知する例
0 3 * * * /usr/local/bin/backup.sh || \
curl -X POST -H ‘Content-type: application/json’ \
–data ‘{“text”:”backup failed on ‘$(hostname)'”}’ \
https://hooks.slack.com/services/XXX/YYY/ZZZ
“`
### ステップ4: テストとデバッグ
“`bash
# 手動でスクリプトを実行確認
/usr/local/bin/backup.sh
# cronと同じ環境を模してテスト
env -i bash -c ‘/usr/local/bin/backup.sh’
# cronのログを追跡
sudo journalctl -u cron -f # Debian系
sudo journalctl -u crond -f # Red Hat系
sudo grep CRON /var/log/syslog
# 一時的に5分後に実行して動作確認
echo “$(date -d ‘+5 min’ +’%M %H’) * * * /usr/local/bin/backup.sh” | crontab –
“`
## 注意事項
– cronで実行するスクリプトには必ずシバン (`#!/usr/bin/env bash`) を書く
– 相対パスはダメ。`cd` するか、すべて絶対パスで書く
– 標準出力・標準エラーは必ずリダイレクトしてログを残す
– 重い処理は `flock` で同時実行を防止。CPU/IO過負荷を避けられる
## まとめ
1. **シバン**: スクリプト先頭に `#!/usr/bin/env bash` を必ず
2. **絶対パス**: cron環境はPATHが短いので明示する
3. **ログ**: `>> log 2>&1` で出力を確実に記録
4. **排他**: `flock` で多重起動を防ぐ
5. **通知**: 失敗時はSlackやメールでアラート
関連記事:
– [crontabの書き方と設定方法](../linux-crontab-setup/)
– [シェルスクリプトの基本的な書き方](../linux-shell-script-basics/)
– [シェルスクリプトのエラー処理と終了コード](../linux-shell-error-handling/)




