インフラエンジニアの羅針盤

インフラエンジニア1〜3年目のための技術ガイド

AlmaLinux 9 cron/systemd timer設定

公開更新

サーバー運用では、バックアップやログローテーション、監視スクリプトなど「定期的に自動実行したいジョブ」が数多くあります。AlmaLinux 9 では、従来の cron に加えて systemd timer による定期実行も標準で利用できます。本記事では、crontab の書式から systemd timer の作成、cron から timer への移行判断、排他制御やデバッグまで、企業のサーバー運用チームで求められる知識を手順つきで整理しています。

目次
  1. コマンド早見表
  2. 前提条件
  3. 1. cron の基本
    1. crond の稼働確認
    2. crontab の書式
    3. 特殊文字列(ショートカット)
    4. ユーザー crontab の操作
  4. 2. システム cron
    1. /etc/crontab
    2. /etc/cron.d/ ディレクトリ
    3. /etc/cron.{hourly,daily,weekly,monthly}/
  5. 3. cron の実務設定
    1. 環境変数の設定
    2. 出力のリダイレクト
    3. cron のアクセス制御
  6. 4. anacron
    1. パッケージの確認
    2. /etc/anacrontab の書式
  7. 5. systemd timer の基本
    1. 既存の timer を確認する
    2. timer ユニットの主要なオプション
    3. OnCalendar の書式検証
    4. 自作の timer / service を作成する
  8. 6. systemd timer の実務設定
    1. 排他制御(多重起動の防止)
    2. cron での排他制御(flock)
    3. エラー通知(OnFailure)
    4. ログ確認と手動テスト
  9. 7. cron から systemd timer への移行
    1. 機能比較
    2. 移行例
  10. 8. 実践シナリオ
    1. バックアップジョブ
    2. ディスク容量監視
  11. 9. トラブルシューティング
    1. cron ジョブが動かない
    2. cron ジョブの出力が確認できない
    3. cron.daily のスクリプトが実行されない
    4. systemd timer が発火しない
    5. timer の実行が指定時刻からずれる
  12. AlmaLinux 9 総合リファレンスガイド シリーズ一覧

コマンド早見表

やりたいことコマンド
ユーザー cron 一覧表示crontab -l
ユーザー cron 編集crontab -e
ユーザー cron 削除crontab -r
他ユーザーの cron 確認crontab -u <user> -l
システム cron 確認cat /etc/crontab
cron.d 配下の確認ls /etc/cron.d/
run-parts 対象確認run-parts –test /etc/cron.daily
anacrontab 確認cat /etc/anacrontab
timer 一覧表示systemctl list-timers –all
timer 有効化・起動systemctl enable –now xxx.timer
timer 手動テストsystemctl start xxx.service
timer ログ確認journalctl -u xxx.service
OnCalendar 書式検証systemd-analyze calendar “書式”
crond サービス状態systemctl status crond

前提条件

項目
OSAlmaLinux 9.6(Sage Margay)
cronie1.5.7-13.el9(cronie-anacron 含む)
systemd252
実行ユーザー一般ユーザー(crontab)/ root(システム cron、systemctl)

1. cron の基本

cron は UNIX 系 OS で長年使われている定期実行の仕組みです。crond デーモンが常駐し、登録されたジョブを指定時刻に実行します。

crond の稼働確認

ジョブを登録する前に、crond が動作していることを確認します。

実行コマンド:

# systemctl status crond

実行結果:

● crond.service - Command Scheduler
     Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; preset: enabled)
     Active: active (running)

active (running) かつ enabled になっていれば、crond は稼働中で OS 起動時にも自動起動します。

crontab の書式

crontab の各行は「いつ」「何を」実行するかを 6 つのフィールドで定義します。

┌───────────── 分 (0 - 59)
│ ┌───────────── 時 (0 - 23)
│ │ ┌───────────── 日 (1 - 31)
│ │ │ ┌───────────── 月 (1 - 12)
│ │ │ │ ┌───────────── 曜日 (0 - 7, 0と7は日曜日)
│ │ │ │ │
* * * * * コマンド

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

特殊文字意味
*すべての値* = 毎分 / 毎時 / 毎日
*/nn ごと(ステップ)*/5 = 5 分ごと
a-ba から b の範囲1-5 = 月曜〜金曜
a,b,cリスト指定1,3,5 = 月・水・金

曜日フィールドの数値は 0 = 日曜日 で始まり、7 も日曜日として扱われます。

特殊文字列(ショートカット)

crontab では数値指定の代わりに、以下の特殊文字列を使って直感的にスケジュールを記述できます。

特殊文字列等価な書式意味
@reboot(起動時に 1 回)OS 起動時に実行
@hourly0 * * * *毎時 0 分に実行
@daily0 0 * * *毎日 0:00 に実行
@weekly0 0 * * 0毎週日曜 0:00 に実行
@monthly0 0 1 * *毎月 1 日 0:00 に実行

ユーザー crontab の操作

各ユーザーは自分の crontab を持つことができます。ユーザー crontab の実体は /var/spool/cron/<ユーザー名> に格納されますが、直接編集せず crontab コマンドで操作します。

現在のユーザー crontab を一覧表示するコマンドです。

実行コマンド:

$ crontab -l

実行結果:

no crontab for developer

ジョブが未登録の場合はこのように表示されます。crontab を編集するには crontab -e を実行します。EDITOR 環境変数に設定されたエディタ(デフォルトは vi)が開きます。

root 権限で他ユーザーの crontab を確認する場合は -u オプションを使います。

実行コマンド:

# crontab -u developer -l

crontab -r の誤実行に注意

crontab -r は確認なしでユーザーの crontab をすべて削除します。-e(編集)と -r(削除)はキーボード上で隣接しているため、誤って実行してしまう事故が起きやすいコマンドです。対策として、crontab を編集する前に crontab -l > ~/crontab_backup_$(date +%Y%m%d).txt でバックアップを取得しておくことを推奨します。

2. システム cron

ユーザー crontab とは別に、システム全体で管理する cron 設定があります。root が管理する定期ジョブはこちらに配置します。

/etc/crontab

システム crontab は /etc/crontab に配置されています。ユーザー crontab との違いは、コマンドの前に「実行ユーザー名」フィールドがある点です。

実行コマンド:

# cat /etc/crontab

実行結果:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

AlmaLinux 9 のデフォルトでは、/etc/crontab にはジョブの定義がなく、環境変数のみが記載されています。実際のシステムジョブは /etc/cron.d/ ディレクトリに配置されています。

/etc/cron.d/ ディレクトリ

/etc/cron.d/ には、パッケージやシステム管理者が配置するジョブ定義ファイルが格納されます。書式は /etc/crontab と同じ(ユーザー名フィールドあり)です。

実行コマンド:

# cat /etc/cron.d/0hourly

実行結果:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly

この設定により、毎時 1 分に root ユーザーで /etc/cron.hourly/ 内のスクリプトが run-parts コマンドで一括実行されます。

/etc/cron.d/ のファイル名にドットを含めない

/etc/cron.d/ に配置するファイル名にドット(.)を含めると、crond はそのファイルを無視します。たとえば backup.shcleanup.cron のような名前では読み込まれません。backup-dailycleanup のように、英数字・ハイフン・アンダースコアのみで命名してください。

/etc/cron.{hourly,daily,weekly,monthly}/

これらのディレクトリにスクリプトを配置すると、対応する周期で自動実行されます。cron.hourly/etc/cron.d/0hourly の設定で毎時実行され、cron.dailycron.weeklycron.monthly は anacron 経由で実行されます。

run-parts がどのファイルを実行対象として認識するかは --test オプションで事前に確認できます。

実行コマンド:

# run-parts --test /etc/cron.daily

run-parts は、ファイル名に拡張子(ドット以降)が含まれるファイルを実行対象から除外します。たとえば backup.sh は無視され、backup であれば対象になります。また、実行権限(chmod +x)が付与されていないファイルも除外されます。

3. cron の実務設定

環境変数の設定

cron ジョブが動かない最も多い原因は PATH の問題です。cron が使用するデフォルトの PATH は /usr/bin:/bin のみで、通常のログインシェルとは異なります。

cron の PATH はログインシェルと異なる

ログインシェルでは /usr/local/bin/usr/sbin が PATH に含まれますが、cron のデフォルト PATH には含まれません。スクリプト内でコマンドをフルパスで指定するか、crontab の先頭で PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin を定義してください。

crontab で設定可能な主な環境変数は以下の通りです。

変数デフォルト値用途
PATH/usr/bin:/binコマンド検索パス
SHELL/bin/shジョブ実行に使用するシェル
MAILTOcrontab の所有者ジョブの標準出力・標準エラーの送信先メールアドレス

crontab の先頭に環境変数を定義する例です。

実行コマンド:

$ crontab -e

以下の内容を記述します。

PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
SHELL=/bin/bash
MAILTO=admin@example.corp

0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

出力のリダイレクト

cron ジョブの標準出力と標準エラー出力は、デフォルトでは MAILTO で指定したアドレスにメール送信されます。メールサーバーが設定されていない環境では出力が消失するため、ログファイルにリダイレクトすることを推奨します。

0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

>> で追記、2>&1 で標準エラーも同じファイルに出力します。>(上書き)ではなく >>(追記)を使う理由は、過去のログを保持するためです。

cron のアクセス制御

cron の利用を許可・拒否するユーザーは /etc/cron.allow/etc/cron.deny で制御します。

ファイル動作
cron.allow が存在するcron.allow に記載されたユーザーのみ利用可能
cron.allow がなく cron.deny が存在するcron.deny に記載されたユーザー以外が利用可能
両方とも存在しないroot のみ利用可能

AlmaLinux 9 のデフォルトでは /etc/cron.allow は存在せず、/etc/cron.deny が空の状態で存在します。この状態ではすべてのユーザーが cron を利用できます。

特定のユーザーのみに cron の利用を制限する場合は、/etc/cron.allow を作成して許可するユーザーを記載します。

実行コマンド:

# echo "developer" > /etc/cron.allow

切り戻す場合は /etc/cron.allow を削除すれば、元の動作(cron.deny による制御)に戻ります。

実行コマンド:

# rm /etc/cron.allow

4. anacron

anacron は、サーバーが停止していた間にスキップされたジョブを、次回起動時に補完実行する仕組みです。24 時間稼働ではない開発サーバーや、メンテナンスで定期的に停止するサーバーで役立ちます。

パッケージの確認

AlmaLinux 9 では cronie-anacron がデフォルトでインストールされています。

実行コマンド:

$ rpm -q cronie cronie-anacron

実行結果:

cronie-1.5.7-13.el9.x86_64
cronie-anacron-1.5.7-13.el9.x86_64

/etc/anacrontab の書式

/etc/anacrontab は anacron の設定ファイルです。各行は「期間日数」「遅延分」「ジョブ名」「コマンド」の 4 フィールドで構成されます。

実行コマンド:

# cat /etc/anacrontab

実行結果:

RANDOM_DELAY=45
START_HOURS_RANGE=3-22
1	5	cron.daily		nice run-parts /etc/cron.daily
7	25	cron.weekly		nice run-parts /etc/cron.weekly
@monthly 45	cron.monthly		nice run-parts /etc/cron.monthly

各フィールドの意味は以下の通りです。

フィールド例(cron.daily の場合)意味
期間日数11 日ごとに実行
遅延分5anacron 起動後 5 分待ってから実行
ジョブ名cron.dailyタイムスタンプファイルの識別名
コマンドnice run-parts /etc/cron.dailynice 付きで cron.daily 内のスクリプトを実行

環境変数 RANDOM_DELAY=45 は 0〜45 分のランダムな遅延を追加します。複数サーバーで同時にジョブが走ることによる負荷集中を避ける目的です。START_HOURS_RANGE=3-22 は、anacron がジョブを実行してよい時間帯(3:00〜22:00)を指定しています。

5. systemd timer の基本

systemd timer は、systemd が提供するタイマー機能です。.timer ユニットと .service ユニットのペアで動作します。timer が指定した時刻になると、対応する service を起動してジョブを実行します。

既存の timer を確認する

AlmaLinux 9 にはデフォルトでいくつかの timer が登録されています。

実行コマンド:

# systemctl list-timers --all

実行結果:

NEXT                        LEFT          LAST                        PASSED    UNIT                         ACTIVATES
Wed 2026-03-25 01:50:52 JST 1h 17min left Wed 2026-03-25 00:25:46 JST 7min ago  dnf-makecache.timer          dnf-makecache.service
Wed 2026-03-25 14:44:36 JST 14h left      Tue 2026-03-24 14:44:36 JST 9h ago    systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Thu 2026-03-26 00:00:00 JST 23h left      Wed 2026-03-25 00:00:46 JST 32min ago logrotate.timer              logrotate.service

各列の意味は次の通りです。

  • NEXT:次回の実行予定時刻
  • LEFT:次回実行までの残り時間
  • LAST:前回の実行時刻
  • PASSED:前回実行からの経過時間
  • UNIT:timer ユニット名
  • ACTIVATES:timer が起動する service ユニット名

timer ユニットの主要なオプション

timer ユニットの [Timer] セクションで使用する主なオプションです。

オプション説明
OnCalendarカレンダー形式で実行時刻を指定OnCalendar=daily
OnBootSecOS 起動からの経過時間で指定OnBootSec=10min
OnUnitActiveSecservice の前回起動からの経過時間で指定OnUnitActiveSec=1h
AccuracySec実行時刻の精度(デフォルト 1min)AccuracySec=1h
RandomizedDelaySecランダムな遅延の最大値RandomizedDelaySec=60m
Persistent前回実行されなかった分を起動時に補完Persistent=true

既存の timer の設定を確認してみます。

実行コマンド:

# systemctl cat logrotate.timer

実行結果([Timer] セクション):

[Timer]
OnCalendar=daily
AccuracySec=1h
Persistent=true

OnCalendar=daily は毎日 0:00 に実行する設定です。AccuracySec=1h により最大 1 時間の幅で実行タイミングが調整されます。これはシステム負荷を分散する目的です。Persistent=true により、サーバー停止中にスキップされたジョブは次回起動時に実行されます。

OnCalendar の書式検証

systemd-analyze calendar コマンドで、OnCalendar に指定する書式が意図通りのスケジュールになるか事前に検証できます。

実行コマンド:

$ systemd-analyze calendar "Mon..Fri *-*-* 09:00:00"

実行結果:

Normalized form: Mon..Fri *-*-* 09:00:00
    Next elapse: Wed 2026-03-25 09:00:00 JST
       From now: 8h left

Normalized form で正規化された書式を確認でき、Next elapse で次回実行時刻を確認できます。本番に投入する前に必ずこのコマンドで検証してください。

自作の timer / service を作成する

毎日 3:00 にバックアップスクリプトを実行する timer を作成する例です。まず service ユニットを作成します。service が「何を実行するか」を定義し、timer が「いつ実行するか」を定義します。

実行コマンド:

# cat /etc/systemd/system/backup-daily.service

以下の内容で作成します。

[Unit]
Description=Daily backup script

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
StandardOutput=journal
StandardError=journal

Type=oneshot は、スクリプトが完了するまで待ち、完了後にユニットの状態を inactive に戻す設定です。定期実行のジョブでは oneshot を使います。StandardOutput=journal により出力が journald に記録されます。

次に timer ユニットを作成します。

実行コマンド:

# cat /etc/systemd/system/backup-daily.timer

以下の内容で作成します。

[Unit]
Description=Run daily backup at 03:00

[Timer]
OnCalendar=*-*-* 03:00:00
AccuracySec=5min
Persistent=true

[Install]
WantedBy=timers.target

AccuracySec=5min で実行精度を 5 分以内に設定しています。デフォルトの 1 分よりも緩くすることで、他のジョブとの同時実行を避けつつ、過度に厳密なタイミング制御によるシステム負荷を抑えます。[Install] セクションの WantedBy=timers.targetsystemctl enable 時に timers.target に組み込むための設定です。

ユニットファイルを作成したら、daemon-reload で systemd に認識させ、timer を有効化・起動します。

実行コマンド:

# systemctl daemon-reload

実行コマンド:

# systemctl enable --now backup-daily.timer

enable --now は enable(自動起動の有効化)と start(即時起動)を同時に行います。timer が登録されたことを確認します。

実行コマンド:

# systemctl list-timers backup-daily.timer

timer と service のファイル名を揃える

timer ユニットは、同名の service ユニット(backup-daily.timerbackup-daily.service)を自動的に紐づけます。ファイル名を揃えておけば、timer の [Timer] セクションに Unit= を明示する必要はありません。

6. systemd timer の実務設定

排他制御(多重起動の防止)

ジョブの実行時間が予想以上に長引いた場合、次回のスケジュール時刻に前回のジョブがまだ実行中という事態が起こり得ます。同じジョブが同時に複数走ると、データの不整合やリソース競合の原因になります。

systemd timer の場合、service に Type=oneshot を指定していれば、前回の service が完了するまで次回の起動は待機されます。これにより多重起動が防止されます。

cron での排他制御(flock)

cron には systemd のような排他制御の仕組みがないため、flock コマンドでロックファイルを使った排他制御を行います。

0 */1 * * * /usr/bin/flock -n /tmp/backup.lock /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

-n オプションはロックが取得できない場合(前回のジョブが実行中の場合)に即座に終了します。-w 60 に変更すると、最大 60 秒間ロックの取得を待ちます。運用要件に応じて選択してください。

エラー通知(OnFailure)

systemd timer で実行した service が失敗した場合に、別のユニットを起動して通知する仕組みが OnFailure= です。

まず通知用の service を作成します。

実行コマンド:

# cat /etc/systemd/system/notify-failure@.service

以下の内容で作成します。

[Unit]
Description=Send failure notification for %i

[Service]
Type=oneshot
ExecStart=/opt/scripts/notify-failure.sh %i

@ 付きのユニット名はテンプレートユニットです。%i にはインスタンス名(呼び出し元のユニット名)が入ります。

バックアップ service の [Unit] セクションに OnFailure= を追加します。

[Unit]
Description=Daily backup script
OnFailure=notify-failure@%n.service

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
StandardOutput=journal
StandardError=journal

%n は現在のユニット名(backup-daily.service)に展開されます。バックアップが失敗すると notify-failure@backup-daily.service が起動し、通知スクリプトが実行されます。

ログ確認と手動テスト

timer で実行された service のログは journalctl で確認します。

実行コマンド:

# journalctl -u backup-daily.service

timer のスケジュールを待たずに service を手動で実行してテストするには、service を直接起動します。

実行コマンド:

# systemctl start backup-daily.service

実行後、ステータスを確認します。

実行コマンド:

# systemctl status backup-daily.service

Active: inactive (dead) かつ Result: success と表示されれば、oneshot の service が正常に完了したことを意味します。Result: exit-code の場合はスクリプトがエラー終了しているため、journalctl でログを確認してください。

7. cron から systemd timer への移行

systemd timer は cron の上位互換ではなく、それぞれに適した用途があります。移行を検討する際は、以下の比較を参考にしてください。

機能比較

機能cronsystemd timer
ログ出力自前でリダイレクトが必要journald に自動記録
依存関係なしAfter= / Requires= で他ユニットとの依存を定義可能
リソース制御なしCPUQuota= / MemoryMax= でリソース制限可能
状態確認ログを確認するしかないsystemctl status で即座に確認可能
排他制御flock を使って自前で実装Type=oneshot で標準対応
失敗時通知MAILTO(メール依存)OnFailure= で任意の処理を起動
停止中の補完anacron が必要Persistent=true で対応
秒単位のスケジュール不可(最小単位は分)OnCalendar で秒単位まで指定可能

移行例

以下の cron ジョブを systemd timer に移行する例です。

移行前の crontab 設定:

30 2 * * * /opt/scripts/cleanup.sh >> /var/log/cleanup.log 2>&1

移行後の service ユニット(/etc/systemd/system/cleanup-daily.service):

[Unit]
Description=Daily cleanup script

[Service]
Type=oneshot
ExecStart=/opt/scripts/cleanup.sh
StandardOutput=journal
StandardError=journal

移行後の timer ユニット(/etc/systemd/system/cleanup-daily.timer):

[Unit]
Description=Run daily cleanup at 02:30

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

移行手順は次の通りです。

  1. 上記の service / timer ユニットファイルを作成する
  2. systemctl daemon-reload で systemd に認識させる
  3. systemctl enable --now cleanup-daily.timer で有効化・起動する
  4. systemctl start cleanup-daily.service で手動テストする
  5. テスト成功を確認してから crontab の該当行を削除する

移行すべきでないケース

以下のケースでは cron のまま運用する方が合理的です。

  • チーム全員が cron に習熟しており、systemd timer の学習コストが見合わない場合
  • 既存の運用手順書や監視設定が cron 前提で構築されている場合
  • 1 行の crontab で済む単純なジョブを、2 ファイル(timer + service)に分ける必然性がない場合

8. 実践シナリオ

バックアップジョブ

毎日 3:00 に /opt/data を tar.gz で /backup に保存するジョブを、cron 版と systemd timer 版の両方で示します。

cron 版

実行コマンド:

# crontab -e

以下の行を追加します。

0 3 * * * /usr/bin/flock -n /tmp/backup-data.lock /usr/bin/tar czf /backup/data-$(date +\%Y\%m\%d).tar.gz -C /opt data >> /var/log/backup-data.log 2>&1

crontab 内の % は改行として解釈されるため、\% でエスケープする必要があります。flock で多重起動を防止し、ログをファイルにリダイレクトしています。

systemd timer 版

service ユニット(/etc/systemd/system/backup-data.service):

[Unit]
Description=Backup /opt/data
OnFailure=notify-failure@%n.service

[Service]
Type=oneshot
ExecStart=/usr/bin/tar czf /backup/data-%Y%m%d.tar.gz -C /opt data
StandardOutput=journal
StandardError=journal

timer ユニット(/etc/systemd/system/backup-data.timer):

[Unit]
Description=Run data backup at 03:00

[Timer]
OnCalendar=*-*-* 03:00:00
AccuracySec=5min
Persistent=true

[Install]
WantedBy=timers.target

timer 版では、ログは journald に自動記録され、排他制御は Type=oneshot で対応し、失敗時通知は OnFailure で設定しています。cron 版で必要だった個別の対策が systemd の標準機能で実現できています。

ディスク容量監視

ディスク使用率が 80% を超えた場合に警告ログを出力するスクリプトを、5 分ごとに実行する例です。

監視スクリプト(/opt/scripts/check-disk.sh):

#!/bin/bash
THRESHOLD=80
df -h --output=pcent,target | tail -n +2 | while read usage mount; do
  usage_num=${usage%\%}
  if [ "$usage_num" -ge "$THRESHOLD" ]; then
    logger -p local0.warning "DISK WARNING: ${mount} is ${usage} full"
  fi
done

timer ユニット(/etc/systemd/system/check-disk.timer):

[Unit]
Description=Check disk usage every 5 minutes

[Timer]
OnBootSec=1min
OnUnitActiveSec=5min
AccuracySec=30s

[Install]
WantedBy=timers.target

OnBootSec=1min で OS 起動 1 分後に初回実行し、OnUnitActiveSec=5min で以降 5 分間隔で繰り返します。監視スクリプトのような高頻度ジョブでは AccuracySec を短く(30 秒)設定して、実行タイミングのばらつきを抑えています。

9. トラブルシューティング

cron ジョブが動かない

cron ジョブが期待通りに動作しない場合、最も多い原因は PATH の問題です。ログインシェルでは動作するコマンドでも、cron の環境では PATH が異なるため見つからないことがあります。

確認方法として、cron のログを確認します。

実行コマンド:

# tail -20 /var/log/cron

対処方法は 2 つあります。

  1. crontab の先頭に PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin を追加する
  2. スクリプト内のコマンドをすべてフルパス(例:/usr/bin/tar)で記述する

cron ジョブの出力が確認できない

ジョブは実行されているがログが残らない場合、出力のリダイレクトが設定されていない可能性があります。

対処方法として、crontab のコマンド末尾にリダイレクトを追加します。

>> /var/log/job-name.log 2>&1

MAILTO が設定されていてメールサーバーが動作していれば、ジョブの出力はメールで送信されます。しかし、メールサーバーが未設定の環境では出力が破棄されるため、ファイルへのリダイレクトを基本としてください。

cron.daily のスクリプトが実行されない

/etc/cron.daily/ に配置したスクリプトが実行されない場合、以下の 2 点を確認してください。

ファイル名に拡張子が含まれていないか:run-parts はファイル名にドット(.)を含むファイルを無視します。backup.sh ではなく backup という名前にしてください。

実行権限が付与されているか:実行権限がないファイルも run-parts の対象外です。

実行コマンド:

# chmod +x /etc/cron.daily/backup

対象として認識されているか確認するには、以下のコマンドを実行します。

実行コマンド:

# run-parts --test /etc/cron.daily

このコマンドの出力にファイルパスが表示されれば、実行対象として認識されています。

systemd timer が発火しない

timer ユニットファイルを配置したのに発火しない場合、以下の 2 点が原因であることが多いです。

daemon-reload を実行していない:ユニットファイルを新規作成・変更した場合は、systemd に再読み込みさせる必要があります。

実行コマンド:

# systemctl daemon-reload

timer を enable していない:enable しないと OS 再起動後に timer が起動しません。

実行コマンド:

# systemctl enable --now backup-daily.timer

timer の状態は systemctl status backup-daily.timer で確認できます。Active: inactive (dead) の場合は起動されていません。

timer の実行が指定時刻からずれる

systemd timer にはデフォルトで AccuracySec=1min が設定されており、指定時刻から最大 1 分のずれが発生します。また、RandomizedDelaySec が設定されている場合はさらに遅延が加わります。

正確な時刻に実行する必要がある場合は、AccuracySec=1s のように精度を高く設定します。ただし、精度を上げるとシステム負荷が増加するため、運用要件に応じて判断してください。

[Timer]
OnCalendar=*-*-* 03:00:00
AccuracySec=1s
RandomizedDelaySec=0

切り戻す場合は AccuracySec を元の値(例:1min5min)に戻し、systemctl daemon-reload を実行してください。

AlmaLinux 9 総合リファレンスガイド シリーズ一覧

  1. システム基本情報の確認
  2. 初期設定
  3. ネットワーク設定(nmcli)
  4. パッケージ管理(dnf)
  5. ユーザー・グループ管理
  6. ファイアウォール(firewalld)
  7. SSH設定・鍵認証
  8. systemd / サービス管理
  9. ストレージ・LVM
  10. ログ管理(journalctl / rsyslog)
  11. cron / systemd timer(この記事)
  12. セキュリティ強化
  13. パフォーマンス監視
  14. コンテナ管理(Podman)
  15. バックアップ・リストア
前の記事
次の記事