为什么从 Makefile 调用时 diff 会失败?

Mar*_*tus 7 make diff patch

我正在尝试解决的补丁问题的缩小范围:只有两个文件,每个文件的大小为 1 个字节:

  • 文件a(包含'a'
  • 文件b(包含'b')和

目标是制作并应用一个补丁来改变'b'to的值'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
Run Code Online (Sandbox Code Playgroud)

鉴于上述情况,make失败并显示以下输出:

$ make
diff -u b a > b2a.patch
make: *** [patch] Error 1
Run Code Online (Sandbox Code Playgroud)

但是,如果我在 bash shell 上一个接一个地执行 Makefile 中的命令,则完全没有问题。

der*_*ert 11

Make 假设退出代码 0 表示成功,其他任何代码都表示失败。这是几乎所有命令行工具使用的标准约定。

不幸的是,diff不是其中之一。检查 GNU 差异信息页面,以及单一 Unix 规范“差异”条目,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 ]
Run Code Online (Sandbox Code Playgroud)

请注意; [ $$? -eq 1 ]我添加到两条差异线末尾的位。; test $$? -eq 1当然,您也可以使用。所述$?壳变量是$$?由于正常生成文件逸出约定。请注意,这也拒绝退出状态 0(无差异),这可能是您想要的。

顺便说一句:看来这真的应该是:

patch: b.corrected
        diff …
b.corrected: b2a.patch
        patch …
b2a.patch: a b
        diff …
Run Code Online (Sandbox Code Playgroud)

这样 a 和 b 的修改就会被接收,并且文件会正确地重新生成。