Cronはどのように動くのか?
Cronは非常にシンプルなUNIXユーティリティです。これは2つの部分で動作します。Cronはまず、最初にシステムを起動したときにバックグラウンドプロセスとして実行されます。
そこから、1 分毎に特定のファイルを読み込みます。このファイルにはコマンドのリストが含まれており、順番に、実行したい各スクリプトやプログラムのタイムコードとファイルパスで構成されています。 このアプローチにより、cronは大規模なシステムにおいて高い柔軟性を発揮することができます。例えば、Cronieのような最近のcron実装は、そのマシンが複数のユーザーをホストしていても、単一のcronのインスタンスしか実行しません。 Cronieは、システムにインストールされた各ユーザーのローカル・クーロンタブを提供することで、これを可能にしています。そのため、cronは誰がそのcrontabを所有しているか、そのユーザーの権限レベル、そしてcrontab内のコマンドを知るだけでよいのです。 これはシステムをより効率的にするだけでなく、メモリ上で実行される特権プログラムの量を減らすことによって、より安全にします。Crontab: Cronの心臓部
すべてのcronの実装は、何らかの形でcrontabを使用しています。これは単純なテキストファイルで、cronが特定のユーザのために実行する全てのコマンドを含んでいます。上記のように、システム内の各ユーザーは自分自身のクーロンタブを持っています。以下のコマンドを実行することで見ることができます。
crontab -l
これは現在のユーザのcrontabの内容を標準出力に表示します。これは、そのユーザーのために実行されているcronのコマンドを素早く確認したい場合に、非常に便利です。
これを編集するには、コマンドを実行する必要があります。crontab -e
これはクーロンにデフォルトのテキストエディタを起動させ、その中にクーロンタブ・ファイルをロードするように指示します。これで、crontabファイルを編集することができます。
Crontabの構文
crontabファイルの文法は非常にシンプルです。このファイル内の1行は、その特定のユーザーに対して実行される必要がある対応するコマンドを表します。crontab コマンドの一般的な形式は以下のようなものです。
m h d mon dow [flags] コマンド
time-interval は 5 桁のフィールドで、コマンドを実行する頻度を cron に伝えることができます。これはどんなcronの実装でも核となる機能で、cronが定期的なタスクをどのように扱うかについて、具体的かつ柔軟に設定することが可能です。
- m = 0から59までの分
- h = 0から23までの時間
- d = 1から31までの月日
- mon = 1から12までの月
- dow = 0から6までの曜日。0は日曜日である。
flags フィールドは cron が一つのコマンドに対してどのように振る舞うかを変更するためのオプションのセットです。例えば、
-n`オプションを含めると、cronがシステムメールを送信しないようにすることができます。
30 2 24 7 \* /home/$USER/myscript.sh
注意: 注意**:異なるcronジョブが互いに重ならないように、「一般的でない」分数(11、27 34など)でcronジョブを実行することをお勧めします。
ショートコード
Crontab では、cron のエントリを読みやすくするために、いくつかのショートコードを使用することができます。
@reboot
- スタートアップ時に一度だけ実行します。@yearly
- 1年に1回、“0 0 1 1 *”.> を実行します。@annually
- @yearlyと同じです。@monthly
- 1ヶ月に1回実行、“0 0 1 1 *”.> *@weekly
- 1ヶ月に1回実行、“0 0 1 1 *”.@weekly
- 1週間に1回実行、“0 0 ╱ 1 ╱ 0” *@daily
- 1週間に1回実行。@daily
- 1日1回実行、“0 0 ㏄* ㏄* ㏄*”.@midnight
- @dailyと同じです。@hourly
- 1時間に1回実行、“0 ╱╱╱*"。
例えば、以下のような感じです。
例)@daily ramces /home/ramces/.scripts/file-backup.sh
また、ショートコード @reboot
を使用すると、起動時に実行するスクリプトを作成することができます。
@reboot /home/ramces/.scripts/bootup.sh
これは、マシンの電源を入れたらすぐにコマンドが実行されるようにする方法を作成したい場合に、非常に便利です。
注意: 注意**: あなたのシステムの設定によっては、@reboot
ショートコードはあなたのシステムで意図したとおりに動くかもしれませんし、動かないかもしれません。
システムクローンタブ
cronのもう一つの素晴らしい特徴は、rootのcrontabファイルを作成することでシステム全体の定期的なタスクを管理することができることです。これは、システムのメンテナンスとアップデートを自動化したい場合、非常に便利です。
root crontab を作成するには、コマンドで sudo
を使用するか、root アカウントにログインします。
sudo crontab -e
システムcrontabは、ユーザーのcrontabとほぼ同じ形式をとっています。しかし、この2つの重要な違いの1つは、root crontabではシステム内のどのユーザーとしてもコマンドを実行できることです。
m h d mon dow user [flags] "コマンド"
これを知っていれば、同じ crontab の中でユーザーとルートレベルの両方の再帰的なコマンドを作成するのに使うことができます。
30 2 ╱︎日root /bin/apt update
30 5 ╱︎╱︎╱︎ラムセス /home/ramces/.scripts/file-backup.sh
このようにすることで、ファイルのパーミッションを維持しつつ、実行するコマンドを一箇所で編集できるようになりました。
別のユーザーでcronエントリーを編集する
rootユーザーでcrontabを編集する代わりに、他のユーザーでcronジョブをスケジュールしたい場合、-u
フラグを使用することでも可能です。
sudo crontab -u username -e
例えば、“www-data “ユーザとしてcronジョブを実行するには、以下のコマンドを使用します。
sudo crontab -u www-data -e
cronの動作を確認する
これで特定のコマンドやスクリプトを実行するように設定されましたが、実行されたことを確認したい場合があります。cronに組み込まれているのは、一度コマンドが実行されると、cronのオーナーにメールを送るというものです。これは “MAILTO “変数で変更することができます。
MAILTO=youremail@yourdomain.com` を追加すると、すべてのcronジョブのレポートを指定されたメールに送信します。この変数は通常、crontabの編集画面の一番上に見つけることができます。しかし、もしそこになければ、変数を追加すれば、期待通りに動作します。
複数のメールアドレスはカンマで区切ることができます。もし別のコマンドを別の場所にメールする必要がある場合は、コマンドの真上にMAILTOコマンドを追加します。そのmailtoの後のコマンドは新しいアドレスにメールされます。MAILTO=`を空白にすると、cronエントリの所有者に通知が送られます。 もし、メールを受け取りたくない場合は、cronのログをチェックすることもできます。ほとんどのシステムで、クーロンログにアクセスするには、スーパーユーザの権限が必要です。cronログは、"/var/log “の下にあります。cronまたはsyslogファイルは実行されたcronエントリのログを表示します。sudo grep crontab syslog
Frequently Asked Questions (よくある質問)
なぜ私のcronコマンドは1時間に1回ではなく、1分ごとに実行されるのですか?
これは、crontabを管理する際に最もよくある落とし穴の一つです。デフォルトでは、タイムコードにアスタリスクの値を追加すると、その値で可能なすべてのインスタンスで実行されることを意味します。例えば、0 12 * * *
という値は、1日に1回、午後12時までにコマンドを実行したいことをcronに伝えます。
しかし、ほとんどの初心者は同じタイムコードを * 12 * * *
と書くことが多いようです。このように書くと、コマンドは午後12:00から午後12:59まで1分間に1回実行されることになります。このように、コマンドが1回しか実行されないことを確認するために、分フィールドに0を書くのは良い習慣です。
cronで使える他のオプションはありますか?
nと
MAILTO 変数以外に、
s` コマンドを使用して、プログラムにコマンドの実行を厳しく指示することができます。このオプションを使うと、cronは現在のコマンドが終了するまで、そのコマンドにのみフォーカスするように強制されます。これはあなたのマシンが特定の順番で実行される必要があるコマンド群を使用している場合に、非常に便利です。
また、SHELL
変数を使用して、cronがコマンドに別のシェルを使用するように設定することもできます。例:SHELL=/bin/ksh
。