毎週・毎月の定期処理を全自動化|cronの曜日指定・毎月実行 完全ガイド

定期実行・ジョブ

手作業で回しているバックアップ/レポート作成/ログ整理――これらはすべて 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つ自動化して成功体験を。次に月次・四半期の重い処理も、同じ型で着実に全自動へ。

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント