手作業で回しているバックアップ/レポート作成/ログ整理――これらはすべて cron に任せて“いつも同じ品質で”自動化できます。
本記事は 「毎週/毎月」の実務ジョブを確実に回すための設計・書き方・テンプレ群 を一気にまとめました。コピペOK、現場でそのまま使えます。
どんな課題を解決する?
- 「毎週◯曜にやるはずが抜ける」をゼロに(ヒューマンエラー削減)
- 実行の時刻・頻度・順序を機械に固定 → 品質を均一化
- ログ保存/通知/多重起動防止まで含めた“運用可能な自動化”を構築
まずは最小セット(共通ヘッダ)
crontab -eで以下を先頭に置くと安定します。
# 実行環境の明示
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
CRON_TZ=Asia/Tokyo # タイムゾーン(対応cronで有効)
# ログはジョブごとに出し分けるのが吉
多重起動を必ずブロック(事故防止の基本)
# 例: /usr/bin/flock -n /var/lock/<任意名>.lock <コマンド>
曜日・月の基本書式(おさらい)
分 時 日 月 曜 コマンド
m h dom mon dow command
- 曜日は 0/7=日, 1=月 … 6=土
*(すべて) /1-5(範囲) /1,15(列挙) /*/5(ステップ)
@記法(覚えると速い)
@weekly … 週1回(日曜の深夜/環境依存) @monthly … 月1回(毎月1日深夜)
※「平日だけ」「第◯月曜」「月末」などは自前で条件を足すのが実務的。
【毎週】よく使うパターン集(コピペ可)
平日のみ 19:30 に実行
30 19 * * 1-5 /usr/bin/flock -n /var/lock/work.lock /path/to/job.sh >> /var/log/job.log 2>&1
週次(月曜 07:00)に実行
0 7 * * 1 /usr/bin/flock -n /var/lock/weekly.lock /path/to/weekly.sh >> /var/log/weekly.log 2>&1
土日だけ 10:00 に実行
0 10 * * 6,0 /usr/bin/flock -n /var/lock/weekend.lock /path/to/weekend.sh >> /var/log/weekend.log 2>&1
隔週実行(偶数週の月曜 07:00)
週番号
%Vを使って条件分岐(日本は週の起点が月曜なので扱いやすい)
0 7 * * 1 /usr/bin/flock -n /var/lock/biweekly.lock bash -lc '
if (( $(date +%V) % 2 == 0 )); then /path/to/biweekly.sh; fi
' >> /var/log/biweekly.log 2>&1
【毎月】よく使うパターン集(コピペ可)
毎月1日 03:00 に実行(典型的な月次)
0 3 1 * * /usr/bin/flock -n /var/lock/monthly.lock /path/to/monthly.sh >> /var/log/monthly.log 2>&1
月末 23:50 に実行(最終日だけ)
「28–31日のいずれか」+「翌日が1日なら実行」という判定が堅牢
50 23 28-31 * * /usr/bin/flock -n /var/lock/eom.lock bash -lc '
if [[ $(date -d tomorrow +%d) == "01" ]]; then /path/to/eom.sh; fi
' >> /var/log/eom.log 2>&1
第1月曜 07:00 に実行
当月1〜7日に“かつ月曜”だけ走らせる
0 7 1-7 * 1 /usr/bin/flock -n /var/lock/1st-mon.lock /path/to/first_monday.sh >> /var/log/first_monday.log 2>&1
第3水曜 02:00 に実行
15〜21日の“水曜”に限定
0 2 15-21 * 3 /usr/bin/flock -n /var/lock/3rd-wed.lock /path/to/third_wed.sh >> /var/log/third_wed.log 2>&1
偶数月 の1日 04:30
30 4 1 */2 * /usr/bin/flock -n /var/lock/even-month.lock /path/to/even_month.sh >> /var/log/even_month.log 2>&1
四半期(1/4/7/10月) の1日 05:00
0 5 1 1,4,7,10 * /usr/bin/flock -n /var/lock/qtr.lock /path/to/quarterly.sh >> /var/log/quarterly.log 2>&1
月末“営業日” 19:00(簡易:翌日が土日ならその前営業日に実行)
祝日考慮は別途カレンダーファイルで拡張(後述)
0 19 28-31 * * /usr/bin/flock -n /var/lock/eom-biz.lock bash -lc '
# 明日が土日なら今日/昨日に前倒し
if [[ $(date -d tomorrow +%u) -ge 6 ]]; then /path/to/eom_business.sh; fi
' >> /var/log/eom_business.log 2>&1
複雑な条件を“安全に”書くコツ
- 本体処理はシェルに寄せる:cron行は最短に、判定は
bash -lc '…'で - フルパスで書く:
/usr/bin/rsync/usr/bin/python3 set -euo pipefailをスクリプト先頭に(異常終了を検知)flockで多重起動を防ぐ(ジョブの破壊的重複を回避)- ログ出力+ローテーション(
logrotateを /etc/logrotate.d に)
logrotate雛形(週次で圧縮、90日保持)
/var/log/monthly.log {
weekly
rotate 12
compress
missingok
notifempty
copytruncate
}
実務テンプレ(貼るだけで使える)
1) 週次バックアップ(平日 02:00、失敗時メール通知)
0 2 * * 1-5 /usr/bin/flock -n /var/lock/backup.lock bash -lc '
/usr/local/bin/backup.sh >> /var/log/backup.log 2>&1 || {
echo "Backup failed on $(hostname) at $(date)" \
| mailx -s "[ALERT] backup failed" ops@example.com
exit 1
}
'
2) 月次レポート生成→メール送信(毎月1日 06:00)
0 6 1 * * /usr/bin/flock -n /var/lock/report.lock /usr/local/bin/monthly_report.sh \
>> /var/log/monthly_report.log 2>&1
3) 第1月曜にキャッシュ全再生成
0 3 1-7 * 1 /usr/bin/flock -n /var/lock/recache.lock /usr/local/bin/recache.sh >> /var/log/recache.log 2>&1
4) 四半期請求書バッチ(1/4/7/10月 の 09:00)
0 9 1 1,4,7,10 * /usr/bin/flock -n /var/lock/invoice.lock /usr/local/bin/invoice_batch.sh >> /var/log/invoice.log 2>&1
祝日除外や社内カレンダー連携
「祝日や会社休日は回さない」は cron 単体では難題。判定をスクリプト化するのが王道です。
#!/usr/bin/env bash
# is_business_day.sh
set -euo pipefail
HOLIDAYS="/etc/business_holidays.txt" # YYYY-MM-DD を1行1日で列挙
today="$(date +%F)"
dow="$(date +%u)" # 6=土,7=日
if [[ $dow -ge 6 ]]; then exit 1; fi
if [[ -f $HOLIDAYS ]] && grep -qx "$today" "$HOLIDAYS"; then exit 1; fi
exit 0
cron側:
0 9 * * 1-5 bash -lc '/usr/local/bin/is_business_day.sh && /path/to/job.sh' \
>> /var/log/job_bizday.log 2>&1
トラブルシュート(“動かない”を潰すチェックリスト)
systemctl status cron(Deb系)/crond(RHEL系)が active- スクリプトに 実行権限 と シバン(
#!/usr/bin/env bash) - フルパス指定でコマンドを呼んでいる
- 改行コードは LF(Windows由来は
dos2unix) - 相対パス依存になっていない(
cdを前提にしない) - ログで原因を確認:
tail -n 200 /var/log/<job>.log - メール通知が来ない → MTA/SMTP リレー設定・ポリシーを確認
まとめ(実務で効く自動化の型)
- 曜日/毎月のスケジュールは「cron + 条件分岐」で表現できる
- 月末/第◯曜日/隔週/偶数月・四半期も安全なパターンで実装可能
- flock・ログ・通知を標準装備にして、**“回る仕組み”**に仕上げる
まずは小さなジョブを1つ自動化して成功体験を。次に月次・四半期の重い処理も、同じ型で着実に全自動へ。

コメント