かなり詰まったのでメモ。
環境
cron
cronの設定方法は2つある
crontab
コマンドを使う方法/env/cron.d
にcrontabファイルを置いておく方法
crontabコマンドを使う方法
概要
この方法のメリット
- 簡単で、管理者でなくても設定できる
この方法のデメリット
- ユーザーごとに単一のcrontabファイルを使うため、もし誤って
crontab -r
で削除してしまうと全部消える(人によってはこちらは非推奨とするらしい)
コマンド
# crontabを閲覧 crontab -l # crontabを編集 crontab -e
設定方法
# m h dom mon dow command
分 時 日 月 曜日 コマンド
例えば次のような感じに書く。
# 全部* → 1分ごと * * * * * [command] # 毎時0分に実行 0 * * * * [command] # 毎日0:00に実行 0 0 * * * [command]
また、5つの*の部分の代わりに@monthlyなどの書き方をしても良い (Ubuntu Manpage: crontab - cron を駆動するための一覧表)
cronの起動
sudo service cron start
/etc/cron.d
に置く方法
概要
この方法のメリット
- タスクのジャンルごとにcrontabファイルを分けられるので、本格的な使用に向く
- あやまって削除してしまうなんてことは起こりにくい
この方法のデメリット
- 管理者権限で操作する必要がある
crontabファイルの準備
/etc/crontab
のフォーマットを使うのが楽なので、/etc/cron.d
というディレクトリにコピーして編集する。
# test_cronという名前でコピーする場合
cp /etc/crontab /etc/cron.d/test_cron
この際、ファイル名に拡張子をつけない(.
が含まれるファイルは実行されないらしい)
設定方法
crontabコマンドを使う場合と少し異なり、userのフィールドがある。
# m h dom mon dow user command
分 時 日 月 曜日 ユーザー コマンド
例えば次のように書く。
# m h dom mon dow user command * * * * * user echo "test" >> ~/test.log
私が詰まったポイント
私の場合、userをrootにしていたときはcronが動作しなかった。
自分がログイン中のユーザー名にしたところ、ちゃんと動作するようになった。
cronの起動
sudo service cron start
cronの再読み込み
cronデーモンは/etc/cron.d
内のファイルや/etc/crontab
の変更を監視しており、変更はすぐ再読み込みしてくれるはずだが、手動でやる場合は以下のようなコマンドが使える。
# cronの再起動 sudo service cron restart # cronの状態を確認する sudo service cron status
crontabの設定を楽にするサイト
- https://crontab.guru/
- 5つの
*
のフィールド → 自然言語(英語)に変換してくれるサイト
- 5つの
- http://www.cronmaker.com/
- ドロップダウンで選択 → 5つの
*
のフィールドに変換してくれるサイト
- ドロップダウンで選択 → 5つの
参考になるサイト
cron力をつけよう!全てのcrontab入門者に贈る9個のテクニック · DQNEO起業日記
↑実践的な話でとてもよかった
追記:cronに環境変数を渡す
cronは通常のbashとは異なる環境変数の下で動いている。そのため、Dockerのコンテナに与えた環境変数などがcronのジョブ内で使えない問題が発生する。
そこで、cronを設定する時に
declare -p | grep '\-x' > /cron.env
みたいな感じに必要な環境変数をファイルに書き出しておいて、cronの設定ファイル内で
BASH_ENV=/cron.env DIR=/path/to/workdir # m h dom mon dow user command * * * * * root /bin/bash "${DIR}/main.sh" > "${DIR}/cron.log" 2>&1
のようにして読み込むことで環境変数を渡すことができる。