Jenkinsでシェルスクリプトを-eオプションなしで実行したい
最近Jenkinsを使い始めたが、Jenkins上でシェルスクリプトを書くと、特に何も指定していなくても #!/bin/sh -xe
として実行されてしまうようだ。
普通であれば、スクリプトの途中であってもエラーが出れば即ビルド失敗となるので助かる仕様だろう。
しかし今回は、ビルドの過程で以下のようなことをやりたかった。
nc -z 0.0.0.0 80 if [ $? -ne 0 ]; then docker-compose down exit 1 else ... fi
dockerで起動させたwebアプリケーションを、seleniumで自動テストしたい。そこで正常に起動したかどうかを判定するために、 nc -z 0.0.0.0:8000
を叩く。通じなければdockerコンテナを停止させて終了する、という流れだ。
しかしJenkinsでは #!/bin/sh -xe
として実行されるので、ncコマンドが失敗した時点で即終了となる。else句の中にも入らないのでdockerも立ち上がりっぱなしだ。
dockerを落とすのを忘れたくなかったので、なんとか回避する方法がないか調べてみた。
#!/bin/sh
をつけてみる
軽く調べて出てきたのがこれ。Jenkins内のシェルスクリプトの冒頭に #!/bin/sh
をつけ、設定を上書きするというもの。
しかしこれでは解消しなかった。今回はwebアプリケーションがpython環境だったため、プラグインとしてshiningpandaを使っており、ビルド手順の項目でもshiningpandaの下でシェルスクリプトを実行するようにしていた。
コードを確認したわけではないが、shiningpandaの仕様として常に-xeがつけられてしまう可能性もある。
シェルスクリプトでexit codeを受け渡す
そこでさらに調べた結果、シェルスクリプトの書き方で対応することができた。
exc=0 nc -z 0.0.0.0 80 || exc=1 if [ $exc -ne 0 ]; then docker-compose down exit 1 else ... fi
||
は、前の処理の結果が偽だった場合のみ、後ろの処理を行うというもの。このため、ncコマンドが失敗した場合、 ||
によってexc変数に1が入る。これをつけたことで、 ncコマンドの成否に関わらず nc -z 0.0.0.0 80 || exc=1
の行は最終的に処理され、次の行に進むことができる。
そしてif句でexc変数の値を判定し、dockerを落とすことができる。
シェルスクリプトの経験値が浅いのでこれは考えつかなかったが、 ||
でつなぐのはいろいろなシーンで使えそうだ。