CentOSを運用しているとき、クーロン(Cron)の設定で苦戦したので、その時調べたことと解決策のメモを残しておきます。
どういう事象かというと、ちゃんとcrontabにシェルスクリプトを設定しているはずなのに処理を実行してくれません。
今回自分がCronに設定していたシェルスクリプトは以下の通りです。
見出しテキスト
- Cronが起動しているか確認する
- Cronの実行権限を確認する
- 実行ファイルの権限と所有者を確認する
- Cronの ログの確認
CentOSを運用しているとき、クーロン(Cron)の設定で苦戦したので、その時調べたことと解決策のメモを残しておきます。
どういう事象かというと、ちゃんとcrontabにシェルスクリプトを設定しているはずなのに処理を実行してくれません。
今回自分がCronに設定していたシェルスクリプトは以下の通りです。
0 1 * * * /usr/bin/php /var/sample/batch/Sample01.php `date -d " 1 day ago" +'%Y%m%d'` >> /dev/null 2>&1
察しのいい方ならもう気づくかもしれませんが、、、Cronが動かないときにすべきことを、順を追って説明していきたいと思います。
Cronが起動しているか確認する
まず初めに、Cron自体が立ち上がっているか調べます。
CentOS6以前の場合
# 確認
$ service crond status
# 起動
$ sudo service crond start
CentOS7以降の場合
# 確認(crond.service => rondでも可)
$ systemctl status crond.service
# 起動(crond.service => rondでも可)
$ systemctl start crond
Cronの実行権限を確認する
crontabを使っている場合は、設定した権限と実際に処理を実行する権限が正しいか整理して確認する必要があります。
crontabは「crontab -e」のコマンドを実行して、シェルスクリプトを保存したユーザがそのまま処理の実行ユーザになります。
そのため、実際の処理はrootユーザで実行したいのに、ほかの制限ユーザでcronを設定していると、権限周りのエラーで動かないときがありますので注意してください。
実行ファイルの権限と所有者を確認する
上記の実行権限の話に近いですが、ファイル自体の実行権限も気を付けるべきポイントになります。
例えば、cronの実行ユーザが制限ユーザなのに、実行ファイルの所有者がrootで且つ実行権限が他のユーザに付いてない場合は、権限エラーになります。
# ファイルの権限を確認
$ ls -la
drwxr-xr-x. 2 user user 4096 2019-03-08 10:00 .
drwxr-xr-x. 6 user user 4096 2019-03-08 10:00 ..
-rw-r--r--. 1 user user 5233 2019-03-08 10:00 Sample00.php <- ✖所有者が一致するが、実行権限がない
-rwxr-xr-x. 1 user user 1346 2019-03-08 10:00 Sample01.php <- ○所有者、実行権限とも問題なし。実行可能
-rwxr-xr-x. 1 root root 1346 2019-03-08 10:00 Sample02.php <- ○所有者はrootだが、実行権限があるため実行可能
-rw-r--r--. 1 root root 1346 2019-03-08 10:00 Sample03.php <- ✖所有者が一致せず、実行権限もない
権限を変更する場合は以下のコマンドを実行してください。
# 全ユーザに実行権限を付与
$ sudo chmod 777 ./ Sample03.php
$ ls -la
-rwxr-xr-x. 1 root root 1346 2019-03-08 10:00 Sample03.php
# 所有者を変更
$ sudo chmown user:user ./ Sample03.php
$ ls -la
-rw-r--r--. 1 user uer 1346 2019-03-08 10:00 Sample03.php
Cronの ログの確認
Cronが実際に動いているか確認するために、実行ログを確認します。
$ sudo cat /var/log/cron
実際にCronの予約を仕込んで置き、処理の動きをリアルタイムで確認するためにはtailコマンドを使いましょう。
$ sudo tail -f /var/log/cron
ここまで調べても、自分の場合よく分からず軽く途方に暮れる。(> <;)
しかし、実行ログに以下のような記述にきずく。
Mar 8 10:08:01 user CROND[5898]: (user) CMD (/usr/bin/php /var/sample/batch/Sample01.php `date -d " 1 day ago" +')
!?。自分の実行されているシェルスクリプトがdateコマンドのパラメータの途中で切れていました。
よく調べたら先駆者がいました。
dateフォーマットのパーセンテージ(%)はエスケープしないと途中で切れるんですね!
以下のように修正したらちゃんと動きました!
0 1 * * * /usr/bin/php /var/sample/batch/Sample01.php `date -d " 1 day ago" +'\%Y\%m\%d'` >> /dev/null 2>&1
以上です。