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
Code 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=$? | $result | exit |
---|---|---|---|---|
PHP Errorが見つかった | 0 | 到達しない | 9 | exit 1 |
なかった | 1 | 到達する | 1 | 終了しない |
ややこしいね
半年もしたら、忘れているわね
参考記事
【Bash】コマンドの終了ステータスを判定して何かしたい時のイディオム | クロジカ
Bashの話。 コマンドの終了ステータスを判定して何かしたい時、 下記のように書くことがよくある。 ``` o