ファイルが存在しない場合にエラー状態で終了する方法はありますか?私は現在このようなことをしています:
all: foo
foo:
test -s /opt/local/bin/gsort || echo "GNU sort does not exist! Exiting..." && exit
make
を実行すると、all
ターゲットが実行され、foo
が実行されます。
期待されるのは、test -s
条件に失敗した場合、echo/exit
ステートメントが実行されます。
ただし、/usr/bin/gsort
は存在しますが、echo
ステートメントの結果を取得しますが、exit
コマンドは実行されません。これは私が達成したいと思っていることの反対です。
上記のようなことを行う正しい方法は何ですか?
exit
単独では、最後に実行されたコマンドのステータスを返します。この場合、ゼロを返します。つまり、すべてが正常であることを意味します。
これは、||
と&&
に 等しい優先順位 があり、シェルがコマンドが記述されているかのように解釈するためです。
( test ... || echo ... ) && exit
失敗を通知する場合は、ゼロ以外の値で終了する必要があります。 exit 1
。エコーandで終了するには、コマンドを;
で区切って順番に並べます
all: foo
foo:
test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
現時点ではこれは少し古いことを理解していますが、Makeにファイルが存在するかどうかをテストするためにサブシェルを使用する必要さえありません。
また、実行する方法/期待する方法にも依存します。
次のようにワイルドカード関数を使用します。
all: foo
foo:
ifeq (,$(wildcard /opt/local/bin/gsort))
$(error GNU Sort does not exist!)
endif
それを行う1つの良い方法です。ここで、ifeq句はターゲット自体の前に評価されるため、インデントされないことに注意してください。
これをすべてのターゲットで無条件に実行したい場合は、ターゲットの外に移動するだけです。
ifeq (,$(wildcard /opt/local/bin/gsort))
$(error GNU Sort does not exist!)
endif
Makeのすべてのコマンドラインは、独自のサブシェルで実行されます。したがって、exit
を実行すると、そのサブシェルだけが終了します。メイクファイル全体ではありません。デフォルトでは、サブシェルが失敗した終了ステータスを返すと、make
の実行が停止します(慣例により、0は成功を意味するため、他のものは実行を停止します)。最も簡単な方法は、test
コマンドの終了ステータスを使用することです。
all: foo
foo:
test -s /opt/local/bin/gsort
診断メッセージを印刷すると、echo
などのコマンドが終了ステータス0を返し、make
がすべて正常であると判断するため、事態は少し複雑になります。これを回避するには、サブシェルにゼロ以外の終了ステータスを与えるコマンドを実行する必要があります。
all: foo
foo:
test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
または単に
all: foo
foo:
test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; false; }
単純に:
all: /opt/local/bin/gsort
で、もし /opt/local/bin/gsort
が欠落している場合、「ターゲット `/ opt/local/bin/gsort 'を作成するルールがありません」というエラーメッセージが表示されます。
しかし、それを使って素敵な説明もしたい場合は:
/opt/local/bin/gsort:
echo "GNU sort does not exist! Exiting..."
false
GNU/Makeでは、ターゲットが宣言されていない場合は.PHONEY
に依存関係がなく、そのターゲットに一致するファイルが存在しない場合にルールが呼び出されます。
上記のコードは、false
コマンドを/opt/local/bin/gsort
は存在せず、0以外の値を返し、makeは失敗します。
gsort
実行可能ファイルが存在するかどうかを確認しているので、そのためにwhich
またはtype
Shellコマンドを使用できます。
all: foo
:
foo:
which gsort || exit 1
# or
type gsort || exit 1
エラーメッセージは自動的に印刷されるため、必要ありません。
/ bin/sh:行0:タイプ:
gsort
:見つかりません
明らかです。
または、test
または[
(見る: help test
/help [
構文の場合)、例:.
test -x /opt/local/bin/gsort || { echo Error msg; exit 1; }
指定されたファイルが存在し実行可能かどうかを確認し、存在しない場合はメッセージを表示して終了します。括弧は、コマンドをグループ化することにより(左から右へ)演算子の通常の優先順位をオーバーライドするために重要です(Compound Commands
セクションman bash
詳細については)。
別の方法は、ルールのターゲットを使用してファイルが存在するかどうかを確認し、all
に依存関係として追加することです。
all: /opt/local/bin/gsort
@echo Success.
/opt/local/bin/gsort:
@echo "GNU sort does not exist! Exiting..."
exit 1
結果:
$ make
GNU sort does not exist! Exiting...
exit 1
make: *** [/opt/local/bin/gsort] Error 1