エラーログを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_logCode language: Bash (bash)

ところが、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
Code language: Bash (bash)
grep結果grep終了コードresult=$?$resultexit
PHP Errorが見つかった0到達しない9exit 1
なかった1到達する1終了しない

ややこしいね

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

参考記事

【Bash】コマンドの終了ステータスを判定して何かしたい時のイディオム | クロジカ
Bashの話。 コマンドの終了ステータスを判定して何かしたい時、 下記のように書くことがよくある。 ``` o
タイトルとURLをコピーしました