はじめに
定期的に実施する作業は、自動的に実行されるようにcrontabコマンドで/etc/crontab
ファイルに記述するだけと思っていたのですが・・・
# crontab -e
ある時、/var/spool/cron/[user名]
というファイルの存在に気づき、この2つの違いを調べまとめてみました。
→書きながら全く違う方向に進んでしまったので、今回はcrontabの基礎的な使い方にまとめた。
同記事で理解できること
①crontabファイルの記述方法
②シェルスクリプトの書き方
③環境変数パス追加
④リダイレクト・/dev/null・2>&1の使い方
cronの仕組み
/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が月曜日) |
コマンド | 実行すべきコマンド |
複数の値を指定する場合
0 9,12 * * 1 date >> /root/prac/date.log
上の例では、毎週月曜日の9時と12時にdateコマンドの出力結果を/root/prac/date.logに追記します。
間隔を指定する場合
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)
#デフォルトゲートウェイに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
課題
同タスクで環境変数のパス追加を忘れていた場合、どのようにすればその事実に気付けるのか?ログから「環境変数のパス追加してないから実行されない」と問題把握するまでの手順を調べる