🚀 ニフティ’s Notion

【サーバ運用入門2024 #5】cron

cronについて

時間ベースのジョブスケジューラです。スクリプトやコマンドを定期的に自動的に実行するジョブをスケジュールできます。

crontab

crontabは、現在のユーザーのcronジョブを一覧表示または編集するためのコマンドです。 crontab -e コマンドを使用して、自分専用のcrontabファイルを編集することができます。このファイルには、実行するコマンドと、それを実行するスケジュールを指定する行を追加します。

crontab -r でcron設定全削除になるので要注意!!キーが隣です!!!

cronの設定方法

cronジョブは、分、時間、日、月、曜日を指定する5つのフィールドで構成されるスケジュール式によって定義されます。これらのフィールドはスペースで区切られ、コマンドは最後のフィールドの後に続きます。

* * * * * command
| | | | |
| | | | |
| | | | +---- Day of the Week   (range: 1-7 Mon-Sun, 0-6 Sun-Sat)
| | | +------ Month of the Year (range: 1-12)
| | +-------- Day of the Month  (range: 1-31)
| +---------- Hour              (range: 0-23)
+------------ Minute            (range: 0-59)

※このコメントをコメントアウトして設定ファイルの一番上に書いておくと便利です。

例えば、毎週火曜日の8時30分に/home/ec2-user/example1.shを実行したいときは、このように書きます。

30 8 * * 2 /bin/bash /home/ec2-user/example1.sh

複数指定や範囲指定も可能です。

# 月曜日から金曜日の午後515分にスクリプトを実行する。
15 17 * * 1-5 /bin/bash /home/ec2-user/example1.sh

# 月の10日と20日の午前2時にスクリプトを実行する。
0 2 10,20 * * /bin/bash /home/ec2-user/example1.sh

昔からよく使われているものなので、トリッキーな設定方法も検索で大体出てきます。

なお、crontabコマンドで設定した内容は /var/spool/cron/crontabs/user に保存されます。が、少しでも分からない部分があれば直接編集するべきではありません。権限等が間違っていると正しく動作しないので、 crontab コマンドを使って編集しましょう。

crontab設定演習

crontabコマンドで実際に設定してみます。

初回はエディタを選択します( select-editor コマンドで変更も可能です)。

2番のvimを選択してください。他を選んでもいいですが自己責任で。

crontab -r でcron設定全削除になるので要注意!!キーが隣です!!!

sci02189@NIFTY-6768 ~ % crontab -e
no crontab for sci02189 - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:

以下の一行を一番下に追加してください。(ホームディレクトリの名前は各自の名前に合わせてください)

* * * * * /home/ec2-user/example5.sh

crontab -l コマンドで現在の設定を見る事ができます。

数分後にexample5.txtの中身を見てください。

※観察が終わったらcron設定、example5.txtを削除しておいてください。

crontab -e

dd <- 1行削除するvimコマンド

:wq <- 保存して終了

/etc/crontab について

システム全体のcronジョブを管理したい場合は /etc/crontab に記述します。システム全体の設定なので、rootユーザで操作 または sudo で操作する必要があります。

設定方法は crontab コマンドで書いたときと基本は同じですが、 コマンドの前にユーザ名を記入する必要がある ので注意!

* * * * * user-name command
| | | | |
| | | | |
| | | | +---- Day of the Week   (range: 1-7 Mon-Sun, 0-6 Sun-Sat)
| | | +------ Month of the Year (range: 1-12)
| | +-------- Day of the Month  (range: 1-31)
| +---------- Hour              (range: 0-23)
+------------ Minute            (range: 0-59)

システム全体のジョブの毎週・毎月等の定期実行については事前にディレクトリが用意されています。

以下のディレクトリにシェルスクリプトファイルを配置すると、ディレクトリの名前の通りのタイミングで実行されます。

  • /etc/cron.hourly
  • /etc/cron.daily  
  • /etc/cron.weekly
  • /etc/cron.monthly

ユーザが何もしてなくても中身がある場合があります。ls等で覗いてみてください。

余談

/etc/crontab内に、 /etc/cron.hourly などの実行指示が書かれています。

sci02189 ~ % cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
# You can also override PATH, but by default, newer versions inherit it from the environment
#PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

時間が余った人向け

crontabで

* * * * * echo "genki 100% desu!!" >> /home/ec2-user/hoge.txt

と設定してもうまく動きません。直してください。

ヒント1

journalctl -f -u cron でcronのログを見る事ができます。

ヒント2(ほぼ答え)

ログを見ると、実行コマンドが echo "genki 100 で止まっています。%があると止まってしまうようです。

答え

cronでは%があるとコマンドの終端として認識されます。 \ でエスケープすればよいです。