27
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【図解】cronの仕組み

Posted at

はじめに

定期的に実施する作業は、自動的に実行されるようにcrontabコマンドで/etc/crontabファイルに記述するだけと思っていたのですが・・・

# crontab -e

ある時、/var/spool/cron/[user名]というファイルの存在に気づき、この2つの違いを調べまとめてみました。
→書きながら全く違う方向に進んでしまったので、今回はcrontabの基礎的な使い方にまとめた。

同記事で理解できること

①crontabファイルの記述方法
②シェルスクリプトの書き方
③環境変数パス追加
④リダイレクト・/dev/null・2>&1の使い方

cronの仕組み

cron_structure.jpg

/var/spool/cron配下にユーザごとにcrontabファイルが用意されている。
そのcrontabファイルにユーザがスケジューリングしておけばcrondデーモンが1分おきにスケジュールをチェックしてくれるので、記述した時間にジョブが実行される。

覚えること

crontabコマンドのオプション

オプション 説明
-e エディタを使ってcrontabファイルを編集
-l crontabファイルの内容を表示する
-r crontabファイルを削除する
-i crontabファイル削除時に確認する
-u ユーザー名 ユーザを指定してcrontabファイルを編集する(rootのみ)

crontabファイルのフィールド(スケジューリングの書き方)

フィールド 内容
0~59までの整数
0~23までの整数
1~31までの整数
1~12までの整数
曜日 0~7までの整数(1が月曜日)
コマンド 実行すべきコマンド

複数の値を指定する場合

crontab -e
0 9,12 * * 1 date >> /root/prac/date.log

上の例では、毎週月曜日の9時と12時にdateコマンドの出力結果を/root/prac/date.logに追記します。

間隔を指定する場合

crontab -e
0 */2 * * 1 date >> /root/prac/date.log

上の例では、2時間ごとにdateコマンドの出力結果を/root/prac/date.logに追記します。

実践: 1分毎にdateコマンドを実行し実行結果を"date.log"ファイルに追記する

エディタを使ってcrontabファイル編集 ※viコマンドは使えないので注意!

[root@localhost ~]# crontab -e

編集作業

1 #1分毎に日時を対象ファイルに吐き出す
2 */1 * * * * date >> /root/prac/date.log

crontabファイル内容確認

[root@localhost ~]# crontab -l
#1分毎に日時を対象ファイルに吐き出す
*/1 * * * * date >> /root/prac/date.log

Catコマンドでも現在のrootユーザのcronの設定状況が確認できる。

[root@localhost ~]# cat /var/spool/cron/root 
#1分毎に日時を対象ファイルに吐き出す
*/1 * * * * date >> /root/prac/date.log

tail -f出力ログファイルをリアルタイム監視します。crontabファイルで記述した通り、1分毎にdateコマンドが実行されているのがわかります。

[root@localhost ~]# tail -f /root/prac/date.log 
2022年 10月 29日 土曜日 02:35:01 JST
2022年 10月 29日 土曜日 02:36:01 JST
2022年 10月 29日 土曜日 02:37:01 JST
2022年 10月 29日 土曜日 02:38:01 JST
2022年 10月 29日 土曜日 02:39:02 JST
2022年 10月 29日 土曜日 02:40:01 JST
2022年 10月 29日 土曜日 02:41:01 JST
2022年 10月 29日 土曜日 02:42:01 JST
2022年 10月 29日 土曜日 02:43:01 JST
2022年 10月 29日 土曜日 02:44:02 JST

設定済みのcronジョブを削除し確認

[root@localhost ~]# crontab -r
[root@localhost ~]# crontab -l
no crontab for root

応用: 1分毎にシェルスクリプトを実行しその結果を/prac dir内に保存する

スクリプトとログの両方を格納するdirの作成

[root@localhost ~]# pwd
/root
[root@localhost ~]# mkdir prac/sv

シェルスクリプトの作成(prac/sv/test.sh)

prac/sv/test.sh
#デフォルトゲートウェイにping。実行結果はディスプレイにもどっかのファイルにも保存させない。
#戻り値によって処理を変え、日付のログファイル作成。

ping -c 3 192.168.1.1 > /dev/null 2>&1

if [ "$?" -ne 0 ] ; then
( date ; echo "Can't reach to SV" ) >> /root/prac/sv/`date "+%Y%m%d"`.log
else
( date ; echo "SV reachable" ) >> /root/prac/sv/`date "+%Y%m%d"`.log
fi

上のシェルスクリプトの書き方参照先は以下の通り
・リダイレクション> /dev/null 2>&1の詳細:新しいLinuxの教科書P.190~191
・Ifの条件式$?はシェルスクリプトの引数を表す変数:LPIC小豆本P.316
・ログファイル名date "+%Y%m%d"の書き方:LPIC小豆本P.391
・/date "+%Y%m%d".log = $(date "+%Y%m%d")でもいい

このシェルスクリプトは、直前に実行されたコマンド、つまりpingの実行結果の戻り値が0じゃない場合orそれ以外で処理を分けている。

作成したスクリプトに対し、パスの追加及び実行権の付与(小豆本P.113&179&181)

作成したスクリプトのPermissionは644なので実行権を付与する。(744)

[root@localhost ~]# ls -l /root/prac/sv/test.sh 
-rw-r--r--. 1 root root 383 10月 29 03:26 /root/prac/sv/test.sh
[root@localhost ~]# chmod u+x prac/sv/test.sh
[root@localhost ~]# ls -l /root/prac/sv/test.sh 
-rwxr--r--. 1 root root 383 10月 29 03:26 /root/prac/sv/test.sh

パスの追加

[root@localhost ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/dirsc
[root@localhost ~]# PATH=$PATH:/root/prac/sv
[root@localhost ~]# echo $PATH
/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/dirsc:/root/prac/sv

※永続的な使用なら.bashrcに記述

cronの設定

作ったシェルスクリプトを1分毎に走らせる設定し確認

[root@localhost ~]# crontab -l
#1分毎にsh実行
*/1 * * * * /root/prac/sv/test.sh

動作確認(リアルタイム監視)

[root@localhost ~]# tail -f  /root/prac/sv/20221029.log 
2022年 10月 29日 土曜日 04:43:03 JST
SV reachable
2022年 10月 29日 土曜日 04:44:03 JST
SV reachable
2022年 10月 29日 土曜日 04:45:03 JST
SV reachable
2022年 10月 29日 土曜日 04:46:03 JST
SV reachable
2022年 10月 29日 土曜日 04:47:03 JST
SV reachable

cronの設定の消去

[root@localhost ~]# ls -l /var/spool/cron/
合計 4
-rw-------. 1 root root 56 10月 29 04:43 root
[root@localhost ~]# cat /var/spool/cron/root 
#1分毎にsh実行
*/1 * * * * /root/prac/sv/test.sh
[root@localhost ~]# crontab -r
[root@localhost ~]# crontab -l
no crontab for root
[root@localhost ~]# ls -l /var/spool/cron/
合計 0

以上。

反省点と課題

シェルスクリプトに対しパス(環境変数)の追加を忘れていて実行されなかった。
以下のログファイルを見てみたが、よくわからないまま。

[root@localhost ~]# tail -n 20 /var/log/cron
Oct 29 04:38:01 localhost CROND[14203]: (root) CMD (/root/prac/sv/test/sh)
Oct 29 04:39:02 localhost CROND[14274]: (root) CMD (/root/prac/sv/test/sh)
Oct 29 04:40:01 localhost CROND[14349]: (root) CMD (/root/prac/sv/test/sh)
Oct 29 04:41:01 localhost CROND[14427]: (root) CMD (/root/prac/sv/test/sh)
Oct 29 04:42:01 localhost CROND[14509]: (root) CMD (/root/prac/sv/test/sh)
Oct 29 04:42:46 localhost crontab[14572]: (root) LIST (root)
Oct 29 04:42:49 localhost crontab[14573]: (root) BEGIN EDIT (root)
Oct 29 04:43:02 localhost CROND[14600]: (root) CMD (/root/prac/sv/test/sh)
Oct 29 04:43:20 localhost crontab[14573]: (root) REPLACE (root)
Oct 29 04:43:20 localhost crontab[14573]: (root) END EDIT (root)
Oct 29 04:44:01 localhost crond[1289]: (root) RELOAD (/var/spool/cron/root)
Oct 29 04:44:01 localhost CROND[14688]: (root) CMD (/root/prac/sv/test.sh)

PSコマンドも確認

[root@localhost ~]# ps aux | grep 13584
root       15371  0.0  0.0 221940  1080 pts/0    R+   04:55   0:00 grep --color=auto 13584

課題

同タスクで環境変数のパス追加を忘れていた場合、どのようにすればその事実に気付けるのか?ログから「環境変数のパス追加してないから実行されない」と問題把握するまでの手順を調べる

27
26
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
27
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?