unicornのlog rotationでハマったが、実は test コマンドの exit コード起因だったという話

unicorn の log を cron で毎日ローテートする設定を書いたところ、下記エラーメールが届いて「なぜだろう」と数時間唸ってました。ようやく解決に至ったので、メモしておきます。

メール

件名:

Cron <root@***> test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

本文:

/etc/cron.daily/logrotate: error: error running last action script for /path/to/unicorn/log/*.log run-parts: /etc/cron.daily/logrotate exited with return code 1

設定

/etc/logrotate.d に配備した設定ファイル内容は以下の通りです。

/path/to/unicorn/log/*.log {
  daily
  missingok
  rotate 90

  ...

  lastaction
    pid=/path/to/unicorn.pid
    test -s $pid && kill -USR1 "$(cat $pid)"
  endscript
}

原因

ログロテーションは正常に完了しており、"run-parts: /etc/cron.daily/logrotate exited with return code 1" なので last action script に問題がある模様です。

「test -s して存在確認してから実行してるし...何がいけないのかサッパリわからん!」 と思っていたのですが、この test の return code こそが原因でした。

DESCRIPTION
       Exit with the status determined by EXPRESSION.

       --help display this help and exit

       --version
              output version information and exit

       An omitted EXPRESSION defaults to false.  Otherwise, EXPRESSION is true or false and sets exit status.

となっており、test コマンドの成否によって、exit status が設定されるとのこと。

$ test -s /tmp/not_found_file
$ echo $?
1

実際に試してみると、存在しないファイルについては確かに 1 になるようです。。

test -s $pid が false になるのは unicorn を稼働させてなかったからで、これで理屈が通りました。