Skip to content
VDS · アプリとボット

スケジュールタスク:cronとsystemdタイマー

スケジュールタスクの実行方法、手動では動くのにcronでは動かない理由、systemdタイマーに切り替えるべきタイミングを説明します。

更新日 2026年8月23日

バックアップ、証明書の更新、一時ファイルのクリーンアップ、夜間レポート——これらはすべてスケジュールされたタスクです。Linuxでは、これらを解決する方法が2つあります。古典的なcronとsystemdタイマーです。

Cron:クイックスタート

ユーザーのスケジュールは次のように編集します。

crontab -e
crontab -l

行の形式は5つのフィールドとコマンドです。

# min  hour  day  month  day-of-week  command
  0    4    *     *      *            /usr/local/bin/backup.sh
  */15 *    *     *      *            /usr/local/bin/check.sh
  30   3    *     *      0            /usr/bin/systemctl restart myapp

便利なショートカット:@daily、@hourly、@reboot。ジョブがそもそも実行されたかを確認するには:

grep CRON /var/log/syslog | tail -30
journalctl -u cron --since "1 hour ago"

手動ではスクリプトが動くのにcronでは動かない理由

これは最もよくある問題で、原因はほぼ必ず次の3つのうちのどれかです。

環境が異なる。 CronのPATHは最小限で、.bashrcの変数も一切引き継がれません。プログラムには絶対パスを使い、変数はスクリプトの先頭またはcrontabで明示的に設定してください。

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ディレクトリが異なる。 ジョブはユーザーのホームディレクトリで開始されるため、相対パスは別の場所を指してしまいます。常に絶対パスを使用してください。

出力がどこにも行かない。 エラーが発生しても、誰もそれを見ません。ログを書き出しましょう。

0 4 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

もう2つ小さな点があります。cronの行内の%文字は\%とエスケープする必要があり、crontabファイルは改行で終わらなければなりません——そうでないと最後のジョブが無視されます。

ジョブが実行されたことを外部から検証する必要があります。沈黙したcronは成功したcronとまったく同じに見えます。Uptime Kumaでプッシュチェックを設定しましょう。スクリプトが最後にアドレスへpingし、1日間pingがなければアラートを受け取れます。

systemdタイマー

タスクが単一のコマンドより複雑な場合、タイマーのほうが便利です。ジャーナル、依存関係、リソース制限、そして2つのコピーが同時に実行されることへの保護を備えています。

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run nightly backup

[Timer]
OnCalendar=*-*-* 04:00:00
Persistent=true
RandomizedDelaySec=15m

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers
journalctl -u backup.service -n 50

Persistent=trueは、マシンが停止していた場合に逃した実行をキャッチアップします——cronにはこれができません。RandomizedDelaySecは負荷を分散し、十数のタスクが同じ秒に開始しないようにします。

覚えておくべきこと

  • マシンの時刻はデフォルトでUTCです。「午前4時」を設定する前にtimedatectlを確認してください。
  • 重いタスク(アーカイブ、バックアップ検証)はディスクに負荷がかかります。ディスク速度を参照し、夜間にスケジュールしてください。
  • 5分ごとに実行される長時間タスクは、自分自身と重複します。systemdではType=oneshotが役立ち、cronではflockによるロックを使用します。
*/5 * * * * /usr/bin/flock -n /tmp/job.lock /usr/local/bin/job.sh