ジョブスケジューリング - cron/at/systemd timer【LPIC-1 107.2】
この記事で達成できること
crontabの書式(5 フィールド)を読み書きできる- ユーザー crontab とシステム crontab(
/etc/crontab・/etc/cron.d)の違いを説明できる at/atq/atrmで一度だけのジョブを管理できるanacronとsystemd timerの使いどころを判断できるcron.allow/cron.denyによる実行制御を理解できる- 「cron の PATH 問題」など試験頻出の落とし穴を回避できる
LPIC-1 主題 107.2「ジョブスケジューリングによってシステム管理業務を自動化する」の中核。定期バックアップやログローテーションなど、定型作業を人手を介さず自動実行する技術。
どのスケジューラを使うべきか
繰り返し実行なら cron、一度きりなら at、電源が常時入っていないマシンの定期実行なら anacron、systemd 環境での高機能な制御なら systemd timer を選ぶ。これが判断の起点になる。
| 要件 | ツール | 代表コマンド / ファイル |
|---|---|---|
| 毎日・毎時など定期繰り返し | cron |
crontab -e, /etc/crontab |
| 指定時刻に一度だけ | at |
at, atq, atrm |
| 稼働していない時間帯の取りこぼし回避 | anacron |
/etc/anacrontab |
| systemd 統合・依存関係・ログ連携 | systemd timer |
.timer + .service, OnCalendar= |
cron は指定時刻にマシンが起動していなければそのジョブをスキップする。一方 anacron は「前回からの経過日数」で判定するため、ノート PC のように電源が落ちている時間がある環境でも実行を取りこぼさない。
crontab の書式
crontab の各行は「分 時 日 月 曜日 コマンド」の 6 要素で構成される。先頭 5 つが時刻フィールド、6 番目以降が実行するコマンド。
# ┌───────────── 分 (0 - 59) # │ ┌───────────── 時 (0 - 23) # │ │ ┌───────────── 日 (1 - 31) # │ │ │ ┌───────────── 月 (1 - 12) # │ │ │ │ ┌───────────── 曜日 (0 - 7、0と7は日曜) # │ │ │ │ │ # * * * * * 実行するコマンド
各フィールドで使える特殊記号は次のとおり。
| 記号 | 意味 | 例 |
|---|---|---|
* |
すべての値 | 分が * なら毎分 |
, |
値の列挙 | 0,30 は 0 分と 30 分 |
- |
範囲 | 1-5(曜日)は月〜金 |
/ |
間隔(ステップ) | */15(分)は 15 分ごと |
具体例を読んでみる。
*/15 * * * * /usr/local/bin/check.sh 毎15分ごと 0 3 * * * /usr/local/bin/backup.sh 毎日3:00 0 9 * * 1-5 /usr/local/bin/report.sh 平日(月-金)の9:00 0 0 1 * * /usr/local/bin/monthly.sh 毎月1日の0:00
Vixie cron 系では @reboot・@daily・@hourly・@weekly・@monthly・@yearly(@annually)・@midnight といったニックネームも使える。@reboot は cron デーモン起動時に一度だけ実行される。
曜日フィールドの 0 と 7 はどちらも日曜日を指す。試験では「曜日の数字」がよく問われる。0=日曜、1=月曜… 6=土曜、そして 7 も日曜、と覚える。
手順
Step 1: ユーザー crontab を編集する
crontab -e
crontab: installing new crontab
crontab -e はエディタ($EDITOR / $VISUAL で指定)を開き、現在のユーザーの crontab を編集する。保存すると /var/spool/cron/(ディストリビューションにより crontabs/)配下に格納され、cron デーモンが自動的に読み込む。次の行を追記すると、毎日 3:00 にバックアップが走る。
0 3 * * * /usr/local/bin/backup.sh
Step 2: 登録内容を一覧・削除する
crontab -l crontab -r
0 3 * * * /usr/local/bin/backup.sh
crontab -l は登録済みエントリを表示し、crontab -r は crontab を丸ごと削除する。-r は確認なしで消えるため、-l で控えを取ってから実行するのが安全。root は crontab -u user -e / -u user -l で他ユーザーの crontab を操作できる。
crontab -r と crontab -e はキーが隣接しており、誤って -r を打つと全エントリが消える。crontab -l > ~/crontab.bak でバックアップを取っておくとよい。
Step 3: システム crontab を使う
cat /etc/crontab ls /etc/cron.d/
SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron.hourly
/etc/crontab と /etc/cron.d/ 配下のファイルはシステム crontab で、ユーザー crontab と異なり時刻フィールドとコマンドの間に「実行ユーザー」フィールドが入る(6 フィールド構成)。これが試験頻出の差分。/etc/cron.{hourly,daily,weekly,monthly} にスクリプトを置くと、run-parts 経由でそれぞれの周期に実行される。
Step 4: at で一度だけ実行する
at 22:00 tomorrow atq atrm 2
warning: commands will be executed using /bin/sh at> /usr/local/bin/deploy.sh at> <EOT> job 2 at Sat May 31 22:00:00 2026 2 Sat May 31 22:00:00 2026 a user
at は時刻を指定して一度だけジョブを実行する。プロンプトでコマンドを入力し Ctrl+D(<EOT>)で確定する。atq(= at -l)で待ち行列を確認し、atrm 2(= at -d 2)でジョブ番号 2 を削除する。時刻は 10:00・now + 1 hour・midnight・teatime(16:00)など柔軟に指定できる。batch はシステム負荷が下がったタイミングでジョブを実行する点が at と異なる。
Step 5: 実行可否を制御する
cat /etc/cron.allow cat /etc/cron.deny
alice bob
cron の利用は /etc/cron.allow と /etc/cron.deny で制御する。判定ルールは次のとおり。
| ファイルの状態 | 結果 |
|---|---|
cron.allow が存在する |
そこに記載されたユーザーのみ許可 |
cron.allow が無く cron.deny あり |
cron.deny 記載ユーザー以外を許可 |
| 両方とも存在しない | (実装依存)多くはroot のみ、等 |
at も同様に /etc/at.allow / /etc/at.deny で制御する。*.allow が優先され、存在する場合は *.deny は参照されない。
anacron と systemd timer の使い分け
cron は「電源が入っている前提」で動くが、anacron と systemd timer は電源が落ちていた間の取りこぼしを補える。常時稼働サーバーでないなら、この 2 つを検討する価値がある。
anacron
/etc/anacrontab は cron と書式が異なり「日数間隔・遅延(分)・ジョブ識別子・コマンド」の 4 フィールドで記述する。
cat /etc/anacrontab
# period delay job-identifier command 1 5 cron.daily run-parts --report /etc/cron.daily 7 25 cron.weekly run-parts --report /etc/cron.weekly @monthly 45 cron.monthly run-parts --report /etc/cron.monthly
第 1 フィールドが「何日ごとに実行するか」、第 2 フィールドが「起動後に待つ遅延(分)」。anacron は分・時刻を指定できず、日単位の粒度しか持たない。前回実行日を /var/spool/anacron/ に記録し、間隔を超えていれば起動時に実行する。
systemd timer
systemd timer は .timer ユニットと、実際の処理を行う .service ユニットの 2 つで構成する。
systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES Sat 2026-05-31 03:00:00 JST 8h left Fri 2026-05-30 03:00:00 JST 15h ago backup.timer backup.service
.timer 内の OnCalendar= で実行時刻を指定する。OnCalendar=*-*-* 03:00:00 は毎日 3:00、OnCalendar=daily も同義。systemctl list-timers で次回実行・前回実行・対応サービスを一覧できる。systemd timer は依存関係制御・journalctl でのログ確認・Persistent=true による取りこぼし実行(anacron 相当)まで扱える点が強み。
OnCalendar= の書式が正しいかは systemd-analyze calendar "Mon *-*-* 09:00:00" で検証できる。次回トリガー時刻が表示される。
よくあるミスと対処
症状: cron では動くはずのスクリプトが実行されない(PATH 問題)
原因: cron が起動するシェルの PATH は対話ログインシェルより短く、/etc/profile や .bashrc も読み込まれない。コマンドが見つからず失敗する
確認:
* * * * * env > /tmp/cron-env.txt
対処: コマンドは絶対パスで書く(backup ではなく /usr/local/bin/backup)。または crontab 冒頭で PATH=... を明示的に設定する。
症状: スクリプト内の環境変数が未設定で誤動作する
原因: cron は対話シェルの環境変数(LANG・HOME 周辺の独自設定など)を引き継がない。ログインシェル前提のスクリプトが想定外の挙動になる
確認:
crontab -l
対処: スクリプト側で必要な変数を明示設定するか、crontab に LANG=ja_JP.UTF-8 などを書く。ログイン環境を再現したいなら bash -lc 'コマンド' で起動する。
症状: crontab に書いた % 以降が無視される / コマンドが途中で切れる
原因: crontab ではコマンド行の % が改行(標準入力の区切り)として特別扱いされる
確認:
crontab -l
対処: % をそのまま渡したい場合は \% とバックスラッシュでエスケープする。date +\%Y\%m\%d のように記述する。
症状: 曜日と日付を両方指定したのに想定外の日に動く
原因: cron では「日」と「曜日」を両方とも * 以外に指定すると、どちらか一方が一致した日に実行される(AND ではなく OR)
確認:
crontab -l
対処: 仕様として OR 動作になることを理解する。「特定曜日かつ特定日」のような AND 条件は、コマンド側で日付を判定して制御する。
症状: cron の出力(エラー)が見えない
原因: cron はジョブの標準出力・標準エラーをローカルメールでユーザーに送る。メールを確認していないと気づけない
確認:
grep CRON /var/log/syslog
対処: 出力をファイルへリダイレクトする(>> /var/log/myjob.log 2>&1)。MAILTO=address を crontab に書けば送信先を変更でき、MAILTO="" で抑止できる。
作業完了チェックリスト
- [ ]
crontab -eでユーザー crontab を編集しcrontab -lで確認した - [ ] システム crontab(
/etc/crontab)に user フィールドがある点を確認した - [ ]
atでジョブを登録しatq/atrmで管理した - [ ]
/etc/cron.allow/cron.denyの優先順位を理解した - [ ] スクリプトを絶対パスで記述し PATH 問題を回避した
- [ ]
systemctl list-timersで systemd タイマーを確認した
まとめ
| 場面 | コマンド / ファイル | 目的 |
|---|---|---|
| 定期実行(ユーザー) | crontab -e |
自分の定期ジョブを登録 |
| 定期実行(システム) | /etc/crontab, /etc/cron.d |
user 指定付きの定期ジョブ |
| 一度だけ | at, atq, atrm |
指定時刻に単発実行 |
| 取りこぼし防止 | /etc/anacrontab |
非常時稼働マシンの日次処理 |
| systemd 統合 | .timer + OnCalendar= |
依存・ログ・Persistent 実行 |
| 実行制御 | cron.allow / cron.deny |
ユーザー単位の許可・拒否 |
ジョブスケジューリングはシステム運用の自動化基盤。ログ管理やプロセス優先度と組み合わせると、無人運用の信頼性が一段上がる。