set -eとは何か?最初のエラーでスクリプトを失敗させる
set -e(errexit)は、いずれかのコマンドが0以外のexit codeを返したら即座に終了するようshellに指示し、スクリプトが最初の失敗で止まるようにします。
デフォルトでは、shellスクリプトはコマンドが失敗した後も実行を続け、1つの壊れたステップが紛らわしいエラーの連鎖に変わることがあります。set -eはこれを変えます。コマンドが失敗した瞬間にスクリプトが中断します。これは安全なCIスクリプトの要であり、通常はset -euo pipefailの一部として書かれます。
set -eが行うこと
set -eが有効なとき、shellは単純なコマンドが0以外のステータスを返すとすぐに、先に進むのではなく終了します。これは静かな失敗を即座で目に見える停止に変えます。
なぜデフォルトが危険か
set -eがないと、失敗したbuildコマンドはスクリプトを止めないため、次のコマンドが欠けた、または古い出力に対して実行されます。jobが成功を報告することさえあり、本当の失敗を隠します。
重要な注意点
ifや&&の条件内のコマンドは、設計上、除外されます。- pipeline内の失敗は、
pipefailも設定されていない限り捉えられません。 - 関数とsubshellには独自の微妙な点があります。
予期される失敗の扱い
コマンドが失敗を許される場合があります。|| trueを追加してそのステータスを無視するか、ifで囲むことで、予期していた失敗のためにset -eがスクリプト全体を中断しないようにできます。
CIにおけるset -e
CIステップは何かが壊れた瞬間に止まるべきで、そうすれば失敗が本当の原因を指し示します。ステップをset -e(理想的にはset -euo pipefail)で始めると、失敗したコマンドが後の出力に紛れるのではなく、ステップを失敗させます。
マネージドrunnerでの正直な失敗
Latchkeyのrunnerでは、set -eはコマンドが失敗した瞬間にステップを0以外で終了させ、プラットフォームはこれをきれいな失敗として報告します。この明確さは、本物のバグと、リトライできる一時的なインフラの不具合を分けるのに役立ちます。
重要なポイント
- set -eは、最初に失敗したコマンドでスクリプトを終了させます。
- 単独ではpipelineの失敗を捉えません。
pipefailと組み合わせてください。 - CIでは、set -eは静かな失敗を即座で目に見える停止に変えます。