crontabの書き方完全入門【実例付きで基礎から応用まで解説】

Linux/Unixシステムで定期的なタスクを自動実行するには、crontabを使うのが最も効率的です。システム管理者や開発者にとって、crontabの書き方を正しく理解することは必須スキルと言えます。本記事では、crontabの基本構文から実践的な活用方法まで、具体的な実例を交えて徹底解説します。初心者でも理解できるように丁寧に説明しますので、ぜひ最後までお読みください。

目次

crontabとは何か?基本概念を理解する

crontab(クローンタブ)は、Linux/Unix系OSにおいて、定期的にコマンドやスクリプトを実行するためのスケジューリングツールです。システム管理者や開発者にとって、バックアップの自動実行、ログの定期的な整理、データベースのメンテナンスなど、定期的なタスクを自動化するために欠かせないツールとなっています。

crontabの仕組みを理解するには、以下の3つの主要コンポーネントを知っておく必要があります:

  • cronデーモン:システム上で常に稼働しているプロセスで、スケジュールされたタスクを実行します
  • crontabファイル:ユーザーごとに存在する設定ファイルで、実行したいコマンドやスケジュールを定義します
  • crontabコマンド:crontabファイルを編集・管理するためのCLIツールです

cronデーモンはシステム起動時に自動的に起動され、常にバックグラウンドで実行されています。crontabファイルに記述されたスケジュールに基づいて、指定された時刻にコマンドを実行します。

crontabの主な特徴は以下の通りです:

特徴説明
柔軟なスケジューリング分・時・日・月・曜日を細かく指定可能
複数ユーザー対応システム全体のcrontab(/etc/crontab)とユーザー個別のcrontab(~/.crontab)が存在
ログ記録機能実行結果はsyslogに記録されるため、トラブルシューティングが容易
メール通知機能コマンド実行結果をメールで送信可能(デフォルト設定)
セキュリティ機能各ユーザーは自身のcrontabのみ編集可能(root権限が必要な場合を除く)

crontabを使うことで、以下のような作業を自動化できます:

  • システムログの定期的な圧縮・削除
  • データベースのバックアップ
  • ウェブサイトのコンテンツ更新チェック
  • システムの定期的なメンテナンス
  • メール送信や通知の自動化
  • 定期的なレポートの生成

crontabは、システムの安定稼働と効率的な運用に欠かせないツールです。正しく理解し活用することで、手動で行っていた定期的な作業を自動化し、作業効率を大幅に向上させることができます。

crontabの書式と書式ルールを完全マスター

crontabの基本書式

crontabファイルの各行は、以下の書式で記述します:

分 時 日 月 曜日 コマンド

各フィールドの詳細は以下の通りです:

フィールド範囲特殊文字説明
0-59* , – /実行したい分を指定します
0-23* , – /実行したい時を指定します
1-31* , – / ? L W実行したい日を指定します
1-12* , – /実行したい月を指定します
曜日0-7(0と7は日曜日)* , – / ? L #実行したい曜日を指定します
コマンド実行したいコマンドまたはスクリプトを指定します

特殊文字の使い方

crontabでは、以下の特殊文字を使って柔軟なスケジューリングが可能です:

  • *(アスタリスク):全ての値を表します
  • ,(カンマ):複数の値を指定します
  • -(ハイフン):値の範囲を指定します
  • /(スラッシュ):値の増分を指定します
  • ?(クエスチョンマーク):日または曜日いずれかを指定します(いずれか一方のみ有効)
  • L(エル):最後の日または曜日を表します
  • W(ダブリュー):最も近い平日(月曜~金曜)を表します
  • #(シャープ):n番目の曜日を表します(例:2#3 → 第3月曜)

具体的な書式例

以下に、具体的な書式例を示します:

  • 毎日午前3時に実行0 3 * * * /path/to/command
  • 毎週月曜午前2時に実行0 2 * * 1 /path/to/command
  • 毎月1日午前0時に実行0 0 1 * * /path/to/command
  • 毎時0分、15分、30分、45分に実行0,15,30,45 * * * * /path/to/command
  • 平日の午前9時から午後5時まで1時間ごとに実行0 9-17 * * 1-5 /path/to/command
  • 毎月第3金曜日に実行0 0 15-21 * 5 /path/to/command(15日から21日の間で金曜日のみ)
  • 毎月最終日に実行0 0 L * * /path/to/command

注意事項

crontabの書式には以下の点に注意が必要です:

  • パスの完全指定:コマンドやスクリプトのパスは絶対パスで指定します。相対パスでは動作しません。
  • 環境変数の制限:cron環境では通常のログインシェルとは異なる環境変数が設定されます。必要な環境変数は明示的に設定するか、スクリプト内で定義してください。
  • 改行コード:crontabファイルはLF(Unix形式)の改行コードで保存する必要があります。WindowsのCRLFでは正しく動作しません。
  • コメント行:行頭に#を記述するとコメント行となります。
  • 実行ユーザー:crontabは実行するユーザーの権限で実行されます。root権限が必要な場合はrootユーザーでcrontabを編集してください。

crontabのインストールと基本設定

crontabのインストール

ほとんどのLinuxディストリビューションでは、cronパッケージがデフォルトでインストールされています。以下に主要なディストリビューションでのインストール方法を示します:

Debian/Ubuntu系

sudo apt update
sudo apt install cron

Red Hat/CentOS系

sudo yum install cronie
sudo systemctl enable crond
sudo systemctl start crond

Fedora系

sudo dnf install cronie
sudo systemctl enable crond
sudo systemctl start crond

Arch Linux系

sudo pacman -S cronie
sudo systemctl enable cronie
sudo systemctl start cronie

cronサービスの起動と確認

インストール後、cronサービスを起動し、正常に動作していることを確認します:

# サービスの起動(システムによって異なります)
sudo systemctl start cron   # Debian/Ubuntu
sudo systemctl start crond  # Red Hat/CentOS

# サービスの自動起動設定
sudo systemctl enable cron   # Debian/Ubuntu
sudo systemctl enable crond  # Red Hat/CentOS

# サービスの状態確認
sudo systemctl status cron   # Debian/Ubuntu
sudo systemctl status crond  # Red Hat/CentOS

サービスが正常に動作している場合、以下のような出力が表示されます:

● cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2024-01-15 10:30:00 JST; 5min ago
     Docs: man:cron(8)
 Main PID: 1234 (cron)
    Tasks: 1 (limit: 4915)
   Memory: 1.2M
   CGroup: /system.slice/cron.service
           └─1234 /usr/sbin/cron -f

crontabコマンドの基本操作

crontabファイルを編集・管理するための主なコマンドは以下の通りです:

コマンド説明
crontab -e現在のユーザーのcrontabファイルを編集します
crontab -l現在のユーザーのcrontabファイルの内容を表示します
crontab -r現在のユーザーのcrontabファイルを削除します
crontab -u username -e指定したユーザーのcrontabファイルを編集します(root権限が必要)
crontab -u username -l指定したユーザーのcrontabファイルの内容を表示します(root権限が必要)

crontabファイルの編集方法

crontabファイルを編集するには、以下の手順で行います:

  1. crontab -eコマンドを実行します
  2. デフォルトのエディタ(通常はvi)が起動します
  3. 以下の形式でスケジュールを追加します:
    分 時 日 月 曜日 コマンド
  4. 編集が完了したら保存します(viの場合はEscキーを押して:wqと入力)
  5. crontabが正しく更新されたことを確認します:
    crontab -l

例えば、毎日午前3時に/home/user/backup.shを実行する場合は、以下のように記述します:

0 3 * * * /home/user/backup.sh

crontabの環境設定

cron環境では通常のログインシェルとは異なります。このため、スクリプト内で必要な環境変数を明示的に設定するか、crontabファイル内で設定する必要があります。

crontabファイルの先頭に以下のように環境変数を設定できます:

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO="admin@example.com"
HOME=/home/user

これらの設定は、crontabファイル内のコマンド実行前に適用されます。

cronのログ確認

cronの実行結果やエラーは、通常syslogに記録されます。ログを確認するには以下のコマンドを使用します:

# Ubuntu/Debian
sudo grep CRON /var/log/syslog

# Red Hat/CentOS
sudo grep cron /var/log/cron

# 最近のログのみ確認する場合
sudo journalctl -u cron --since "1 hour ago"

実行結果をメールで受信するように設定されている場合は、以下のコマンドでメールを確認できます:

mail

または、システムのメール設定に応じて、以下のコマンドで確認します:

sudo less /var/mail/username

実践!crontabの具体的な使い方と実例集

基本的な実行例

以下に、crontabを活用した具体的な実行例を示します。これらの例は、実際の運用シーンでよく見られるものです。

1. システムログの定期的な圧縮

システムログを毎週日曜日の午前2時に圧縮する例です:

0 2 * * 0 gzip -9 /var/log/syslog

このコマンドは、/var/log/syslogファイルをgzip圧縮します。圧縮後のファイル名は/var/log/syslog.gzとなります。

2. データベースのバックアップ

MySQLデータベースのバックアップを毎日午前1時に実行する例です:

0 1 * * * mysqldump -u root -p'password' database_name > /backup/database_$(date +\%Y\%m\%d).sql

注意:パスワードを直接記述するのはセキュリティ上好ましくありません。以下の方法でセキュリティを向上させることをお勧めします:

  • MySQLのオプションファイル(~/.my.cnf)に資格情報を保存する
  • スクリプトファイル内で資格情報を管理する
  • 環境変数から資格情報を取得する

例えば、~/.my.cnfに以下の内容を記述します:

[client]
user = root
password = your_password

そして、crontabには以下のように記述します:

0 1 * * * mysqldump database_name > /backup/database_$(date +\%Y\%m\%d).sql

3. ウェブサイトのコンテンツ更新チェック

ウェブサイトのコンテンツが更新されたかどうかを毎日午前9時に確認し、更新があればメールで通知する例です:

0 9 * * * /usr/bin/wget -q --spider http://example.com/update_check.php

update_check.phpは、ウェブサイトの更新を検出するPHPスクリプトです。

4. システムの定期的な再起動

毎月1日の午前3時にシステムを再起動する例です:

0 3 1 * * /sbin/shutdown -r now

注意:システムの再起動は慎重に行ってください。特に本番環境では、再起動がサービスに影響を与える可能性があります。

5. ディスク使用量の監視とレポート

毎週金曜日の午後5時にディスク使用量をチェックし、レポートをメールで送信する例です:

0 17 * * 5 df -h | mail -s "Disk Usage Report" admin@example.com

スクリプトを活用した実行例

複雑な処理や複数のコマンドを実行する場合は、シェルスクリプトを作成し、crontabからそのスクリプトを実行するのが一般的です。以下に具体的な例を示します。

1. バックアップスクリプト

/home/user/backup_script.shというファイルを作成し、以下の内容を記述します:

#!/bin/bash

# バックアップ先ディレクトリ
BACKUP_DIR="/backup"

# バックアップ対象ディレクトリ
TARGET_DIR="/home/user/data"

# バックアップファイル名に日付を追加
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_$DATE.tar.gz"

# バックアップ実行
tar -czf $BACKUP_FILE $TARGET_DIR

# バックアップファイルの世代管理(3世代まで保持)
ls -t $BACKUP_DIR/backup_*.tar.gz | tail -n +4 | xargs rm -f

# ログ出力
echo "Backup completed: $BACKUP_FILE" >> /var/log/backup.log

このスクリプトを実行可能にし、crontabに以下のように記述します:

0 2 * * * /home/user/backup_script.sh

2. ログローテーションスクリプト

/home/user/log_rotation.shというファイルを作成し、以下の内容を記述します:

#!/bin/bash

LOG_DIR="/var/log/myapp"
DAYS_TO_KEEP=30

# 古いログファイルを削除
find $LOG_DIR -name "*.log" -type f -mtime +$DAYS_TO_KEEP -delete

# ログファイルを圧縮
find $LOG_DIR -name "*.log" -type f -size +10M -exec gzip {} \;

このスクリプトを実行可能にし、crontabに以下のように記述します:

0 3 * * * /home/user/log_rotation.sh

複数の条件を組み合わせた実行例

crontabでは、複数の条件を組み合わせて柔軟なスケジューリングが可能です。以下に具体的な例を示します。

1. 平日の特定時間帯に実行

平日の午前9時から午後5時まで1時間ごとに実行する例です:

0 9-17 * * 1-5 /path/to/command

2. 特定の月にのみ実行

毎年12月(クリスマスシーズン)にのみ実行する例です:

0 0 1 12 * /path/to/command

3. 特定の曜日の特定日にのみ実行

毎月第1月曜日に実行する例です:

0 0 1-7 * 1 /path/to/command

4. 複数の時間帯に実行

午前9時と午後5時に実行する例です:

0 9,17 * * * /path/to/command

応用編:crontabの高度な活用テクニック

crontabの高度な書式テクニック

crontabの書式を活用して、より複雑なスケジューリングを実現するテクニックを紹介します。

1. 条件付き実行

crontab自体には条件付き実行の機能はありませんが、シェルスクリプト内で条件分岐を実装することで、実行条件を制御できます。例えば、特定のファイルが存在する場合のみ実行するスクリプトです:

#!/bin/bash

TARGET_FILE="/tmp/flag.txt"

if [ -f "$TARGET_FILE" ]; then
    /path/to/command
    rm -f "$TARGET_FILE"
fi

2. 実行結果に基づく条件分岐

コマンドの実行結果に応じて条件分岐を行う例です:

#!/bin/bash

if ! /path/to/check_command > /dev/null 2>&1; then
    /path/to/alert_command
fi

3. 複数のコマンドを同時に実行

複数のコマンドを同時に実行するには、&&または;を使用します:

0 3 * * * /path/to/command1 && /path/to/command2

または

0 3 * * * /path/to/command1; /path/to/command2

前者(&&)はcommand1が成功した場合のみcommand2を実行します。後者(;)は常にcommand2を実行します。

crontabと他のツールとの連携

crontabは単独で使用するだけでなく、他のツールと組み合わせることでさらに強力な機能を実現できます。

1. logrotateとの連携

logrotateは、Linuxシステムにおけるログローテーションを自動化するツールです。crontabと組み合わせることで、より柔軟なログ管理が可能になります。

logrotateの設定ファイル(例:/etc/logrotate.d/myapp)を作成します:

/var/log/myapp/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 myuser mygroup
    sharedscripts
    postrotate
        /usr/bin/systemctl reload myapp
    endscript
}

そして、crontabにlogrotateを実行するスケジュールを追加します:

0 2 * * * /usr/sbin/logrotate -f /etc/logrotate.d/myapp

2. anacronとの連携

anacronは、システムがオフラインの場合でも、オンラインになった際に保留していたジョブを実行するツールです。ラップトップやデスクトップ環境でcronを使用する際に便利です。

anacronをインストールし、設定します:

sudo apt install anacron  # Debian/Ubuntu
sudo yum install anacron  # Red Hat/CentOS

anacronの設定ファイル(/etc/anacrontab)を編集します:

# period   delay   job-identifier   command
1         5       cron.daily       nice run-parts /etc/cron.daily
7         10      cron.weekly      nice run-parts /etc/cron.weekly
@monthly  15      cron.monthly     nice run-parts /etc/cron.monthly

これにより、システムが一定期間オフラインだった場合でも、オンラインになった際に保留されていたジョブが実行されます。

3. systemd timersとの連携

最近のLinuxディストリビューションでは、systemd timersを使用してジョブをスケジューリングすることができます。cronと比較して、以下のような利点があります:

  • より詳細な依存関係の管理
  • ジョブの実行状態の詳細な制御
  • システムリソースの制限設定
  • ジョブの実行結果の詳細なロギング

systemd timerの例を示します:

サービスファイル(/etc/systemd/system/myjob.service)

[Unit]
Description=My scheduled job

[Service]
ExecStart=/path/to/command
User=myuser

タイマーファイル(/etc/systemd/system/myjob.timer)

[Unit]
Description=Run my job daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

これらのファイルを作成後、以下のコマンドで有効化します:

sudo systemctl daemon-reload
sudo systemctl enable myjob.timer
sudo systemctl start myjob.timer

crontabのパフォーマンス最適化

大規模なシステムや多数のcrontabジョブを管理する場合、パフォーマンスの最適化が重要になります。以下にパフォーマンス最適化のテクニックを紹介します。

1. ジョブの分散実行

多数のジョブを同時に実行すると、システムリソースが逼迫する可能性があります。ジョブを分散して実行することで、システムへの負荷を軽減できます。

例えば、以下のようにジョブを分散します:

# 1分ごとに実行するジョブ
* * * * * /path/to/job1.sh

# 2分ごとに実行するジョブ
*/2 * * * * /path/to/job2.sh

# 5分ごとに実行するジョブ
*/5 * * * * /path/to/job3.sh

# 10分ごとに実行するジョブ
*/10 * * * * /path/to/job4.sh

2. ジョブの実行時間の最適化

ジョブの実行時間が長い場合、システムリソースを長時間占有することになります。実行時間を短縮するためのテクニックを紹介します:

  • 並列処理:可能な限り並列処理を活用します
  • 処理対象の絞り込み:必要な処理のみ実行するように最適化します
  • 差分処理:前回実行時から変更された部分のみ処理します
  • キャッシュの活用:可能な限りキャッシュを活用して処理を高速化します

3. ジョブの監視とログ管理

多数のジョブを管理する場合、ジョブの実行状態や実行結果を適切に監視することが重要です。以下に監視とログ管理のテクニックを紹介します。

実行状態の監視

# 実行中のcronジョブを確認
ps aux | grep cron

# ジョブの実行履歴を確認
sudo grep CRON /var/log/syslog

実行結果のログ管理

crontabの実行結果をファイルに出力する例です:

0 3 * * * /path/to/command >> /var/log/myjob.log 2>&1

これにより、ジョブの実行結果をログファイルに記録できます。

ジョブの実行時間の監視

ジョブの実行時間が長すぎる場合、システムに負荷をかける可能性があります。実行時間を監視するスクリプトの例です:

#!/bin/bash

LOG_FILE="/var/log/job_duration.log"
JOB_START=$(date +%s)

/path/to/command

JOB_END=$(date +%s)
DURATION=$((JOB_END - JOB_START))

if [ $DURATION -gt 300 ]; then
    echo "$(date): Job took too long ($DURATION seconds)" >> $LOG_FILE
fi

crontabのトラブルシューティング完全ガイド

crontabが実行されない主な原因と対策

crontabに関するよくある質問と回答

crontabの運用や設定に関する疑問は多岐にわたります。ここでは、実務でよく寄せられる質問とその回答をまとめました。crontabの設定やトラブルシューティングの参考にご活用ください。

Q1. crontabで特定の時間にコマンドを実行したいが、実行されない場合の原因と対処法は?

crontabでコマンドが実行されない主な原因には、環境変数の不足、パスの指定ミス、権限不足、ログの確認不足などが挙げられます。例えば、ユーザー固有の環境変数(例:PATH)が引き継がれないため、フルパスでコマンドを指定するか、環境変数を明示的に設定する必要があります。また、cronの実行ログ(/var/log/syslog/var/log/cron)を確認し、エラーの有無をチェックしましょう。実行権限が不足している場合は、対象のコマンドやスクリプトに実行権を付与します。これらの対処法を試しても解決しない場合は、crontabの構文や実行ユーザーの環境設定を見直してください。

Q3. crontabの「*」や「/」などの記号の意味や使い方を教えてください。

crontabの記号には、時間や日付を柔軟に指定するための特殊な意味があります。例えば「*」は「全ての値」を表し、例えば「* * * * *」は「毎分」を意味します。一方、「/」は「間隔」を指定する際に使用され、例えば「*/5 * * * *」は「5分ごと」を表します。また、「-」は範囲指定に使われ、「0 9-17 * * *」は「9時から17時までの間、毎時0分」を意味します。これらの記号を組み合わせることで、複雑なスケジュールも簡潔に表現できます。詳細は公式のマニュアルやリファレンスをご確認ください。

Q2. crontabでシェルスクリプトを実行する際の注意点は?

crontabでシェルスクリプトを実行する際は、スクリプトの先頭に「#!/bin/bash」などのシェバンを記述し、実行可能な権限を付与することが必須です。また、cron実行時の環境変数はユーザーのログインシェルとは異なるため、フルパスでのコマンド指定や環境変数の明示的な設定が必要です。例えば、PATHHOMEをスクリプト内で再定義するか、crontabファイルにPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binのように記述します。さらに、スクリプト内で標準出力やエラー出力をファイルにリダイレクトすることで、実行結果の確認が容易になります。

Q4. crontabの設定を一時的に無効にしたい場合や、履歴を確認する方法は?

crontabの設定を一時的に無効にするには、該当の行の先頭に「#」を追加してコメントアウトします。これにより、その行は実行されなくなります。また、crontabの履歴を確認するには、crontab -lコマンドを使用します。このコマンドは、現在のユーザーのcrontabファイルの内容を表示します。過去の履歴を確認したい場合は、バックアップファイルやシステムのログ(/var/spool/cron/crontabs/)を確認する方法があります。なお、crontabの編集履歴を完全に削除したい場合は、crontab -rコマンドでファイルを削除できますが、実行中のジョブには影響しないため注意が必要です。

まとめ:crontabを使いこなすためのポイント

crontabは、LinuxやUnix系システムで定期的なタスクを自動実行するための強力なツールです。本記事では、crontabの基本的な書式から実用的な活用方法までを解説しました。まず、crontabの構文は「分 時 日 月 曜日 コマンド」という形式で表され、それぞれのフィールドで実行タイミングを細かく設定できる点が特徴です。次に、定期実行したいコマンドを正確に記述することで、バックアップやログの整理、システム監視などの定型業務を自動化できます。また、crontabの編集には「crontab -e」コマンドを使用し、設定の反映には「crontab -l」で内容を確認する流れが基本となります。

一方で、crontabを運用する際には幾つかの注意点があります。例えば、実行環境の違いによってコマンドの動作が変わる可能性があるため、絶対パスを指定するなどの工夫が必要です。また、ログの出力先を明確にしておくことで、実行結果のトラブルシューティングが容易になります。さらに、システムの負荷を考慮して過度な頻度での実行は避け、必要に応じて実行間隔を調整することが重要です。これらのポイントを押さえることで、crontabをより安全かつ効果的に活用できるでしょう。

【編集・制作ポリシー】
本記事はInfra Academy編集部が各ベンダー公式ドキュメント・エンジニア監修をもとに作成しています。インフラ・クラウド構築は環境により異なります。本番環境への適用前に必ずテストを実施してください。情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。
編集ポリシーはこちら
ABOUT ME
たから
フリーランスIT講師/エンジニア。 ◆経験:IT講師/インフラエンジニア/PM/マネジメント/採用/運用・保守・構築・設計 ◆取得資格:CCNA/CCNP/LPIC-1/AZ-900//サーティファイC言語/情報処理技術者 ◆サイドビジネス:アパレル事業/複数のWEBメディアを運営