December 07, 2020

終了ステータス

make はコマンドが non-zero なステータスで終了すると実行を中断します(Errors in Recipes)。 このため「下手に処理が進んでどこで失敗しているのか分からない」といった事になりにくいですし、異常系をあまり考えずにコマンドを書き連ねられます。

.PHONY: test

test:
	test 0 = 0
	test 1 != 1 # would fail
	test 2 = 2
$ make test
test 0 = 0
test 1 != 1 # would fail
make: *** [Makefile:5: test] Error 1

$ echo $?
2

make は基本的に 0 または 2 の終了ステータスを返します(How to Run make)。 1 を返すのは特殊な実行時だけなので non-zero か正常終了かだけ気にしておけばよいと思います。

sh -ex

処理を中断する動きは sh-e オプションと似ています。

$ man sh
...
-e errexit  If not interactive, exit immediately if any untested command fails.
            The exit status of a command is considered to be explicitly tested
            if the command is used to control an if, elif, while, or until; or
            if the command is the left hand operand of an "&&" or "||" operator.

-x xtrace   Write each command to standard error (preceded by a '+ ') before
            it is executed.  Useful for debugging.

実行したコマンドが non-zero ステータスで終了した場合に即座に終了する -e オプションと、シェルスクリプト内で実際に実行されたコマンドを表示する -x オプションをつけるのはシェルスクリプトを書く際によく使われるプラクティスのひとつです。

これも十分有用ですがしれっと実行を中断するので、失敗に気づきやすくするにはひと手間かけてやる必要があります。

#!/bin/sh

set -e

test 0 = 0
test 1 != 1 # would fail
test 2 = 2
$ sh -x test.sh
+ set -e
+ test 0 = 0
+ test 1 != 1
$ echo $?
1

$? は最後に実行されたコマンドの終了ステータスです。

$ test 0 = 0; echo $?
0
$ test 1 != 1; echo $?
1
$ test 2 = 2; echo $?
0

リンク