エラーログをgrepして PHP Errorが見つかったらexit 1したい

grepは見つかると正常扱い、0を返す

Jenkinsで実行するテスト用のシェルスクリプトでのことです。

シェルスクリプト先頭のシバンで #!/bin/bash -e を設定します。-eオプションは、エラーがあれば、そこで停止します。

次に、/var/log/httpd/error_log をサイズ0にtruncateします。

テストとして、selenium-side-runnerを走らせます。

もう一つのテストとして、/var/log/httpd/error_log を grepします。PHP Error、PHP Warning、PHP Noticeが見つかったら、その内容を表示して、停止したいんですね。

最初は、次のようにしました。

grep "] PHP" $error_log

ところが、PHP Errorがないのに、ここで停止してしまいました。

grepは、見つかると成功、つまりexit codeは0。見つからないと失敗、exit codeは1なんですね。

grep結果exit codeコメント
見つかった0(見つけることに)
成功
見つからなかった1(見つけることに)
失敗

つまり、error_logに「PHP Error」がない、テスト成功しているのに、grepとしては失敗しているので、grepが1を返し、そこで停止してしまいます。

逆に、error_logに PHP Errorがあり、テスト失敗しているのに、grepとしては成功しているので、grepが0を返し、停止せずに、次の処理へ進んでしまいます。

grep結果テスト結果grepの
exit code
コメント
PHP Errorが
見つかった
失敗0(見つけることに)
成功
PHP Errorが
見つからなかった
成功1(見つけることに)
失敗

テストとしての成功/失敗と、grepの成功/失敗が逆なんだね

最終的なコード

次のようにして解決しました。

function assert_nothing_php_error() { my_error_log=$1 # PHP NoticeやPHP Warning、PHP Errorが見つかったら、exit 1 # ------------------------------------------- # grep $? result=$? $result # ------------------------------------------- # 見つかった 0 到達しない 9 # 見つからない 1 到達する 1 # ------------------------------------------- result="9" output=$(grep "] PHP " $my_error_log) || result=$? if [ "$result" == "9" ]; then echo $output exit 1 fi } error_log=/var/log/httpd/error_log sudo truncate --size=0 $error_log selenium_side_runner_main "--base-url http://localhost:1234" assert_nothing_php_error $error_log
grep結果grep終了コードresult=$?$resultexit
PHP Errorが見つかった0到達しない9exit 1
なかった1到達する1終了しない

ややこしいね

半年もしたら、忘れているわね

参考記事

【Bash】コマンドの終了ステータスを判定して何かしたい時のイディオム | ハックノート
Bashの話。 コマンドの終了ステータスを判定して何かしたい時、 下記のように書くことがよくある。 ``` output=$(your_kool_command) if ; then echo "Oops..." exit 1 fi ``` これ、if文の `$?` に想定したコマンドの終了ステータス (この例では `...
タイトルとURLをコピーしました