30

ファイルが存在しない場合にエラー状態で終了する方法はありますか? 私は現在、次のようなことをしています:

all: foo

foo:
    test -s /opt/local/bin/gsort || echo "GNU sort does not exist! Exiting..." && exit

Runningmakeallターゲットを実行し、これは を実行しfooます。

test -s条件が失敗した場合、echo/exitステートメントが実行されることが期待されます。

ただし、存在する場合でも、ステートメント/usr/bin/gsortの結果は得られますが、コマンドは実行されません。これは、私が達成したいと望んでいることの反対です。echoexit

上記のようなことをする正しい方法は何ですか?

4

5 に答える 5

23

exit単独で、最後に実行されたコマンドのステータスを返します。この場合、ゼロが返されます。これは、すべて問題がないことを意味します。

これは、||との優先順位&&等しく、シェルがコマンドを書かれたかのように解釈するためです。

( test ... || echo ... ) && exit

失敗を通知したい場合は、ゼロ以外の値で終了する必要がありますexit 1そして、エコーして終了したい場合は、コマンドを順番に並べて区切ります。;

all: foo

foo:
    test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
于 2013-01-15T23:56:04.610 に答える
9

make のすべてのコマンド ラインは、独自のサブシェルで実行されます。そのため、実行exitするとそのサブシェルが終了するだけで、makefile 全体ではありません。デフォルトでは、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; }
于 2013-01-16T14:32:26.160 に答える
3

単に行う:

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 は失敗します。

于 2016-02-21T11:10:50.340 に答える