0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Linux】cron設定徹底まとめ

0
Last updated at Posted at 2025-10-20

ここでは、これまで議論した内容を「/etc/cron.d を直接編集する場合」にフォーカスして整理します。併せて、ジョブの実行ログを“自前のログファイルに出力”する実践手順を詳しく解説します。

目次

そもそもcronとは?

cron は Unix/Linux で定期的にコマンドやスクリプトを自動実行する仕組みです。
常駐デーモン(多くのディストリでは crond サービス)が、設定ファイル(crontab)を監視・実行します。

設定ファイル
/etc/cron.d/に保管 されており、ここに置かれたファイルが実行されていく。

なぜ /etc/cron.d を使うのか

  • ユーザ欄付き(7フィールド) で、実行ユーザを行内で指定できる(例:root)。
  • 設定をファイル単位で分離でき、アプリごと・用途ごとに管理しやすい。
  • サービス配布やコンフィグ管理(Ansible/Chef等)との相性が良い。

参考:ユーザごとの crontab -e は**ユーザ欄なし(6フィールド)**で、そのユーザ権限で実行されます。/etc/crontab/etc/cron.d と同形式。

書式(/etc/cron.d)

分 時 日 月 曜日  ユーザ  コマンド
  • 例:20分おきに root で実行(bash でスクリプトを叩く)

    /20 * * * *  root  /bin/bash /opt/scripts/process.sh >> /var/log/process.log 2>&1
    
  • 注意

    • ユーザ欄は必須root など)。ここで実行権限を決めるので sudo は不要です。
    • インラインコメント不可:コマンドの後ろに # を置いても“コマンドの一部”。コメントは別行# を先頭に。

実行時間の指定について
毎日13:20に実行したい場合:20 13 * * *
20分間隔で実行したい場合:/20 * * * *

コメントアウト(無効化)

  • 行頭に # を付ければその行は無効化されます。空行も無視されます。

    # 0 * * * *  root  /opt/scripts/job.sh
    15 * * * *  root  /opt/scripts/job2.sh
    
  • ファイルごと停止したい場合は、/etc/cron.d.disabled 等に退避(移動)するのが確実。

“自前のログファイル”に出力する(推奨フロー)

1) cron 行末でリダイレクト

  • 追記し、標準エラーも束ねる

    */20 * * * *  root  /bin/bash /opt/scripts/process.sh >> /var/log/process.log 2>&1
    

2) スクリプト側でログ整形(タイムスタンプ+トレース)

#!/usr/bin/env bash
set -euo pipefail
# 失敗箇所を追いやすくする(詳細が欲しければ -x も追加)
# set -x

# 1行で“以後の出力すべて”をファイルへ送る
exec >>/var/log/process.log 2>&1

echo "[$(date '+%F %T')] start pid=$$"

# ---- 本処理 ここから ----
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cd /opt/scripts  # 相対パスを使うなら先に移動
/usr/bin/curl -fsS https://example.com/health || {
  echo "[$(date '+%F %T')] health check failed"
  exit 1
}
# ---- 本処理 ここまで ----

rc=$?
echo "[$(date '+%F %T')] end rc=$rc"
exit "$rc"

ポイント

  • exec >>/var/log/process.log 2>&1以後の標準出力・エラーを丸ごとファイルへ。cron 行末でのリダイレクトとどちらか片方でもOK(併用も害はない)。
  • PATH を明示、コマンドは極力フルパス(cron の環境は最小限)。
  • 相対パスを使うなら 冒頭で cd(cron 実行時の作業ディレクトリは通常 /)。

3) ログ肥大化への備え(任意)

  • /etc/logrotate.d/process を用意してローテート:

    /var/log/process.log {
        weekly
        rotate 8
        compress
        missingok
        notifempty
        create 0640 root root
        postrotate
            /usr/bin/killall -HUP rsyslogd 2>/dev/null || true
        endscript
    }
    

logrotate.dとは?
ログの自動ローテートを設定するファイル

同時実行の防止(flock

ジョブが重なると不整合の元。排他ロックで多重起動を防ぎます。

*/20 * * * *  root  flock -n /run/process.lock /bin/bash /opt/scripts/process.sh >> /var/log/process.log 2>&1
  • -n:ロック取得できなければ即終了(待たない)。

よくある失敗と対策(チェックリスト)

  • 権限
    • スクリプトに実行権限:chmod +x /opt/scripts/process.sh
    • 上位ディレクトリの“x”権限(実行/探索権)が不足していないか:namei -l /opt/scripts/process.sh
  • 改行コード:Windows 由来だと失敗(CRLF)。dos2unix で LF に。
  • sudo は不要/etc/cron.d ではユーザ欄で権限を指定する(root)。sudo を書くと PATH でこけやすい。

具体例(20分おきに実行、排他+自前ログ)

/etc/cron.d/myapp

MAILTO=""
*/20 * * * *  root  flock -n /run/myapp.lock /bin/bash /opt/scripts/myapp.sh >> /var/log/myapp.log 2>&1

/opt/scripts/myapp.sh

#!/usr/bin/env bash
set -euo pipefail
exec >>/var/log/myapp.log 2>&1
echo "[$(date '+%F %T')] myapp start pid=$$"

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cd /opt/scripts

# 例:Nginx の稼働チェック
if ! pgrep -x nginx >/dev/null; then
  echo "[$(date '+%F %T')] nginx not running"
  exit 1
fi

echo "[$(date '+%F %T')] myapp done rc=0"

まとめ

  • /etc/cron.d は 7 フィールド(分・時・日・月・曜・ユーザ・コマンド)。ユーザ欄で権限を指定し、sudo は不要。
  • ログは自前ファイルに出す>> /var/log/xxx.log 2>&1 を cron 行またはスクリプト側 exec で設定。
  • PATH 明示/絶対パス/作業ディレクトリ/改行コード/実行権限を整える。
  • flock で多重起動を防止し、必要なら logrotate でログ肥大化を抑制。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?