web-dev-qa-db-ja.com

Makefileから呼び出されたときにdiffが失敗するのはなぜですか?

トラブルシューティングしようとしているパッチの問題の絞込み:それぞれ1バイトのサイズの2つのファイルのみ:

  • ファイルa'a'を含む)
  • ファイルb'b'を含む)および

目標は、'b'の値を'a'に変更するパッチを作成して適用することです。 Makefileの内容は次のとおりです。

patch:
        diff -u b a > b2a.patch
        patch -o b.corrected b < b2a.patch
        diff a b.corrected

clean:
        rm -f b2a.patch b.corrected

上記の場合、makeは次の出力で失敗します。

$ make
diff -u b a > b2a.patch
make: *** [patch] Error 1

ただし、Makefileのコマンドをbashシェルで次々に実行すれば、まったく問題ありません。

Makeは、終了コード0が成功を意味し、それ以外は失敗を意味すると想定しています。これは、ほとんどすべてのコマンドラインツールで使用される標準の規則です。

残念ながら、diffはそれらの1つではありません。 GNU diff info page、および Single Unix Specification "diff" entry をチェックすると、0は違いが見つからないことを意味し、1は違いが見つかったことを意味し、≥2はエラーを意味します。

コメントで行ったように、コマンドの前にハイフンを付けることで、終了ステータスを完全に無視するようにMakeに指示できますが、これは実際のエラーを無視します。おそらく、必要なエラーではありません。代わりに、次のことができます。

patch:
        diff -u b a > b2a.patch; [ $$? -eq 1 ]
        patch -o b.corrected b < b2a.patch
        diff a b.corrected; [ $$? -eq 1 ]

2つの差分行の最後に追加した; [ $$? -eq 1 ]ビットに注意してください。もちろん、; test $$? -eq 1も使用できます。 $?シェル変数は、通常のMakefileエスケープ規則により、$$?です。これは終了ステータス0(違いなし)も拒否することに注意してください。これはおそらくあなたが望むものです。

ところで:これは本当にあるべきだと思われます:

patch: b.corrected
        diff …
b.corrected: b2a.patch
        patch …
b2a.patch: a b
        diff …

aとbの変更が取得され、ファイルが正しく再生成されるようにします。

11
derobert