Linuxのcron入門|定期実行タスクの設定方法と実務で使えるcrontab活用術

kento_morota 16分で読めます

サーバー運用では、バックアップの取得、ログの整理、データベースのメンテナンスなど、定期的に繰り返す作業が数多く存在します。これらを毎回手動で行うのは非効率であり、実行忘れのリスクも伴います。Linuxのcronは、こうした定期タスクを自動化するための標準的な仕組みです。

本記事では、cronの基本概念からcrontabの書き方、実務で使える設定例、よくあるトラブルとその対処法までを体系的に解説します。Linuxの基礎基本コマンドを理解した方が、タスク自動化の実践スキルを身につけるのに最適な内容です。

cronとは?定期実行の仕組みを理解する

cronは、Linuxにおけるジョブスケジューラです。指定した日時やスケジュールに従って、コマンドやスクリプトを自動的に実行します。cronデーモン(crond)がバックグラウンドで常駐し、毎分スケジュールを確認して実行すべきタスクがあれば起動します。

cronの構成要素

cronの定期実行には、主に以下の要素が関わっています。

要素 説明
cronデーモン(crond) バックグラウンドで動作し、スケジュールを監視するサービス
crontab ユーザーごとのスケジュール設定ファイル
/etc/crontab システム全体のスケジュール設定ファイル
/etc/cron.d/ パッケージが配置するスケジュール設定ディレクトリ
/etc/cron.daily/ 等 日次・週次・月次で自動実行されるスクリプト配置場所

cronデーモンの状態確認

cronを使う前に、cronデーモンが動作していることを確認しましょう。

# cronデーモンの状態を確認
$ systemctl status cron       # Ubuntu/Debian
$ systemctl status crond      # CentOS/Rocky Linux

# 起動していない場合は起動して自動起動も設定
$ sudo systemctl enable --now cron

cronデーモンはsystemdによって管理されています。プロセス管理の知識があれば、cronデーモンの状態確認もスムーズに行えます。

crontabの書式を理解する

crontabの設定は、決められた書式に従って記述します。この書式を正確に理解することが、cron活用の第一歩です。

crontabの基本書式

# ┌───────────── 分(0-59)
# │ ┌───────────── 時(0-23)
# │ │ ┌───────────── 日(1-31)
# │ │ │ ┌───────────── 月(1-12)
# │ │ │ │ ┌───────────── 曜日(0-7、0と7は日曜日)
# │ │ │ │ │
# * * * * * 実行するコマンド

各フィールドで使える特殊文字は以下のとおりです。

記号 意味
* すべての値にマッチ * = 毎分、毎時 など
, 複数の値を指定 1,15 = 1と15
- 範囲を指定 1-5 = 1から5まで
/ 間隔を指定 */5 = 5ごと

スケジュール設定の具体例

# 毎日午前3時に実行
0 3 * * * /path/to/script.sh

# 毎時0分に実行(1時間ごと)
0 * * * * /path/to/script.sh

# 5分ごとに実行
*/5 * * * * /path/to/script.sh

# 毎週月曜日の午前9時に実行
0 9 * * 1 /path/to/script.sh

# 毎月1日と15日の午前2時に実行
0 2 1,15 * * /path/to/script.sh

# 平日(月〜金)の午前8時から午後6時まで30分ごとに実行
*/30 8-18 * * 1-5 /path/to/script.sh

# 毎年1月1日の午前0時に実行
0 0 1 1 * /path/to/script.sh

定義済みスケジュール文字列

多くのcron実装では、よく使うスケジュールを簡潔に記述できる特殊文字列もサポートしています。

文字列 意味 等価な書式
@reboot システム起動時に1回実行 -
@yearly 年に1回(1月1日 0:00) 0 0 1 1 *
@monthly 月に1回(1日 0:00) 0 0 1 * *
@weekly 週に1回(日曜 0:00) 0 0 * * 0
@daily 1日1回(0:00) 0 0 * * *
@hourly 1時間に1回(0分) 0 * * * *
# システム起動時にサービスを自動実行
@reboot /opt/app/start.sh

# 毎日実行
@daily /opt/scripts/daily-report.sh

crontabの操作方法

crontabの登録・編集・確認・削除はすべてcrontabコマンドで行います。

基本的なcrontab操作

# 現在のcrontabを表示
$ crontab -l

# crontabを編集
$ crontab -e

# crontabを削除(すべてのジョブを削除)
$ crontab -r

# 削除前に確認プロンプトを表示
$ crontab -ri

# 他のユーザーのcrontabを表示(root権限が必要)
$ sudo crontab -l -u tanaka

# 他のユーザーのcrontabを編集
$ sudo crontab -e -u tanaka

crontab -eを初めて実行すると、使用するエディタの選択を求められる場合があります。エディタの操作に不安がある方は、Vimの基本操作ガイドを先に確認しておくと安心です。

システム全体のcron設定

ユーザーのcrontabとは別に、システム全体の定期タスクを設定する方法もあります。

# /etc/crontab(システム全体の設定)
# ユーザー指定フィールドがある点が通常のcrontabと異なる
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=admin@example.com

# 分 時 日 月 曜日 ユーザー コマンド
0 3 * * * root /opt/scripts/backup.sh
*/10 * * * * www-data /opt/scripts/cache-clear.sh

また、スクリプトを以下のディレクトリに配置するだけで自動実行される仕組みも用意されています。

/etc/cron.hourly/    # 1時間ごとに実行
/etc/cron.daily/     # 1日1回実行
/etc/cron.weekly/    # 1週間に1回実行
/etc/cron.monthly/   # 1ヶ月に1回実行

これらのディレクトリは、Linuxのディレクトリ構造における/etcの管理ファイルの一部です。配置するスクリプトには実行権限が必要で、ファイル名に拡張子(.sh等)を含めないことが推奨されています。

実務で使えるcron設定例

ここでは、サーバー運用で実際によく使われるcronの設定例を紹介します。

データベースの自動バックアップ

# 毎日午前3時にMySQLのバックアップを取得
0 3 * * * /usr/bin/mysqldump -u backup_user -p'PASSWORD' --all-databases | /usr/bin/gzip > /backup/mysql/db_$(date +\%Y\%m\%d).sql.gz 2>> /var/log/backup.log

# 7日以上前のバックアップファイルを自動削除
0 4 * * * /usr/bin/find /backup/mysql/ -name "*.sql.gz" -mtime +7 -delete

重要な注意点:crontab内で%はエスケープが必要です。date +%Y%m%dはcrontab内ではdate +\%Y\%m\%dと記述します。これはcronでよくあるトラブルの一つです。

ログファイルの定期クリーンアップ

# 毎週日曜日の午前2時に古いログファイルを圧縮・削除
0 2 * * 0 /opt/scripts/log-cleanup.sh

log-cleanup.shの内容例:

#!/bin/bash
# 30日以上前のログを圧縮
find /var/log/app/ -name "*.log" -mtime +30 -exec gzip {} \;

# 90日以上前の圧縮済みログを削除
find /var/log/app/ -name "*.log.gz" -mtime +90 -delete

echo "$(date '+%Y-%m-%d %H:%M:%S') - Log cleanup completed" >> /var/log/cleanup.log

ログの管理方法について詳しくはログ管理ガイドを参照してください。

サーバー監視とアラート通知

# 5分ごとにディスク使用率を確認し、閾値を超えたらアラート
*/5 * * * * /opt/scripts/disk-alert.sh

disk-alert.shの内容例:

#!/bin/bash
THRESHOLD=85
ALERT_EMAIL="admin@example.com"

df -h | awk 'NR>1 {gsub(/%/,"",$5); if($5 > '"$THRESHOLD"') print $0}' | while read line; do
    echo "ディスク使用率警告: $line" | mail -s "[Alert] Disk usage over ${THRESHOLD}%" "$ALERT_EMAIL"
done

SSL証明書の有効期限チェック

# 毎日午前9時にSSL証明書の有効期限を確認
0 9 * * * /opt/scripts/ssl-check.sh
#!/bin/bash
DOMAIN="example.com"
DAYS_BEFORE=30
ALERT_EMAIL="admin@example.com"

expiry_date=$(echo | openssl s_client -connect "$DOMAIN:443" -servername "$DOMAIN" 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
expiry_epoch=$(date -d "$expiry_date" +%s)
current_epoch=$(date +%s)
days_left=$(( (expiry_epoch - current_epoch) / 86400 ))

if [ "$days_left" -lt "$DAYS_BEFORE" ]; then
    echo "SSL証明書の有効期限が${days_left}日後に迫っています: $DOMAIN" | mail -s "[Alert] SSL Certificate Expiry" "$ALERT_EMAIL"
fi

cronのトラブルシューティング

cronは設定を間違えても即座にエラーが表示されないため、トラブルの原因特定が難しい場合があります。よくある問題と対処法を紹介します。

cronジョブが実行されない場合のチェックリスト

  1. cronデーモンが動作しているか確認
$ systemctl status cron
  1. crontabの書式が正しいか確認
$ crontab -l
  1. スクリプトに実行権限があるか確認
$ ls -la /path/to/script.sh
# 実行権限がない場合
$ chmod +x /path/to/script.sh
  1. コマンドのフルパスを使用しているか確認

cronはユーザーのシェル環境を読み込まないため、PATHが最小限しか設定されていません。コマンドはフルパスで記述するか、crontabの先頭でPATHを明示的に設定してください。

# PATHを明示的に設定
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# コマンドはフルパスで記述
0 3 * * * /usr/bin/python3 /opt/scripts/report.py
  1. cronログを確認
# Ubuntu/Debian
$ grep CRON /var/log/syslog | tail -20

# CentOS/Rocky Linux
$ grep CRON /var/log/cron | tail -20

# systemdのジャーナルで確認
$ journalctl -u cron --since "1 hour ago"

環境変数の問題

cronで最も多いトラブルの一つが環境変数の問題です。cronはユーザーの.bashrc.profileを読み込まないため、シェルで動作するスクリプトがcronでは動かないことがあります。

# crontab内で環境変数を設定する方法
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
HOME=/home/tanaka
LANG=ja_JP.UTF-8
MAILTO=tanaka@example.com

0 3 * * * /opt/scripts/backup.sh

環境変数の仕組みを理解しておくと、cronのトラブル解決が格段にスムーズになります。

出力とエラーの処理

cronジョブの出力を適切に処理しないと、メールが大量に送信されたり、問題の検知が遅れたりします。

# 標準出力と標準エラー出力をファイルに記録
0 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

# 標準出力は破棄し、エラーのみ記録
0 3 * * * /opt/scripts/backup.sh > /dev/null 2>> /var/log/backup-error.log

# 出力をすべて破棄(推奨しない:問題の検知が困難になる)
0 3 * * * /opt/scripts/backup.sh > /dev/null 2>&1

# メール通知(MAILTO設定)
MAILTO=admin@example.com
0 3 * * * /opt/scripts/backup.sh

cronの代替・補完ツール

cronは長い歴史を持つ信頼性の高いツールですが、用途によっては他のツールの方が適している場合もあります。

systemdタイマー

systemdにはタイマーユニットという機能があり、cronの代替として使用できます。systemdタイマーはcronにはない以下のメリットがあります。

  • ジョブの依存関係を設定できる
  • journalctlでログを統合管理できる
  • 起動遅延のランダム化ができる(サーバー負荷の分散)
  • リソース制限(CPU、メモリ)を設定できる
# タイマーユニットの例:/etc/systemd/system/backup.timer
[Unit]
Description=Daily Backup Timer

[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=300
Persistent=true

[Install]
WantedBy=timers.target
# 対応するサービスユニット:/etc/systemd/system/backup.service
[Unit]
Description=Daily Backup

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
User=backup
# タイマーの有効化
$ sudo systemctl enable --now backup.timer

# アクティブなタイマーの一覧
$ systemctl list-timers

systemdタイマーの詳細はsystemdサービス管理ガイドで解説しています。

anacronで実行漏れを防ぐ

anacronは、サーバーが停止していた間に実行されなかったジョブを、次回起動時に自動で実行する機能を持っています。cronは指定された正確な時刻にしか実行しないため、その時点でサーバーがダウンしていたジョブは永久にスキップされます。

# /etc/anacrontab の例
# 日数 遅延(分) ジョブ名 コマンド
1    5    daily-backup    /opt/scripts/backup.sh
7    10   weekly-report   /opt/scripts/weekly-report.sh
30   15   monthly-cleanup /opt/scripts/cleanup.sh

まとめ:cronを使いこなしてサーバー運用を自動化する

本記事では、Linuxのcronによる定期タスク実行の設定方法を解説しました。重要なポイントを振り返ります。

  • crontabの書式:分・時・日・月・曜日の5フィールドで実行スケジュールを指定する
  • crontab -eでユーザーごとのスケジュールを編集する
  • フルパスでコマンドを記述し、環境変数を明示的に設定する
  • 出力リダイレクトでログを適切に記録する
  • %のエスケープを忘れない(crontab内では\%
  • 用途に応じてsystemdタイマーanacronも検討する

cronの自動化はシェルスクリプトと組み合わせることで真価を発揮します。バックアップ、監視、レポート生成などの定型業務を自動化し、サーバー運用の効率を大幅に向上させましょう。

さらに、バックアップと復元パフォーマンス監視のスクリプトをcronで定期実行することで、堅牢なサーバー運用体制を構築できます。

#Linux#cron#タスク自動化
共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

AI活用のヒントをお探しですか?お気軽にご相談ください。

まずは話だけ聞いてもらう