コマンドが失敗してもメイクを停止せず、終了ステータスを確認します


22

コマンドが失敗しても停止しないようにGNU Make 3.81に指示しようとしています(そのため、コマンドの先頭にを付けます-)が、次のコマンドで終了ステータスを確認し、より有益なメッセージを出力したいです。しかし、以下の私のMakefileは失敗します:

$ cat Makefile 
all:
    -/bin/false
    ([ $$? -eq 0 ] && echo "success!") || echo "failure!"
$
$ make
/bin/false
make: [all] Error 1 (ignored)
([ $? -eq 0 ] && echo "success!") || echo "failure!"
success!

上記のMakefileが「成功!」とエコーするのはなぜですか。「失敗!」の代わりに ?

更新:

受け入れられた回答をフォローし、さらに詳しく説明すると、次のようになります。

failure:                                                                                                                                                                                                                                      
    @-/bin/false && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"                                                                                                                                                                 
success:                                                                                                                                                                                                                                      
    @-/bin/true && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"     

2
.ONESHELL:ディレクティブを調査することをお勧めします。
ジョナサンレフラー

.ONESHELLは、1つのシェルですべての受信ブロックを実行します。これにより、最初のコマンドが失敗した場合、次のコマンドが問題なく実行されます。これを防ぐため.SHELLFLAGS = -ecに使用する必要があります。しかし、この場合-、makeはエラーを無視するが、すべてのブロックで失敗するため、プレフィックスをこれ以上使用することはできません(レシートの個人コマンド用)。だから、|| :コマンドを無視する解決策の1つです。しかし、それはクロスプラットフォームではありません(Windowsにはありません|| :または|| true
Paul-AG

回答:


14

Makefileルールの各更新コマンドは、個別のシェルで実行されます。だから$?前回失敗したコマンドの終了ステータスは含まれません。デフォルト値が$の場合は何でも含まれますか?新しいシェルで。だからあなたの[$?-eq 0]テストは常に成功します。


10

あなたはのテストを必要としない$?ので、&&場合作品$?はゼロで、||ゼロ以外の戻り値の場合に進行されます。

そして、マイナス値は必要ありません。なぜなら、作るための戻り値は、その行の最後の進行プログラム呼び出しから取得されるからです。だからこれはうまくいく

失敗:

      @/bin/false && echo "success!" || echo "failure!" 

成功:

      @/bin/true && echo "success!" || echo "failure!"

反対のことが起こります:あなたがあなた自身のメッセージをしたいし、とにかく非ゼロ値でmakeプロセスを壊したいなら、あなたはこのような何かを書く必要があります:

失敗:

      @/bin/false && echo "success!" || { echo "failure!"; exit 1; }

8

GNUメイクのドキュメント

'-'または '-i'フラグが原因でエラーが無視される場合、makeは、シェルが終了したステータスコードを示すメッセージを出力することを除いて、エラーリターンをsuccess同様に扱います。エラーが無視されたと言います。

makeこのような場合にの終了ステータスを利用するにmakeは、スクリプトから実行します:

#!/bin/bash
make
([ $? -eq 0 ] && echo "success!") || echo "failure!"

そしてMakefileに以下を含めます:

all:
    /bin/false
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.