如果命令失败,不要停止makeing,但是要检查退出状态


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将在一个有效的shell中运行所有收货块:如果第一个命令失败,则下一个命令将毫无问题地执行。为防止这种情况,.SHELLFLAGS = -ec应使用。但是在这种情况下,您不能使用-更多的前缀(用于收据的个人命令),因为make会写出该错误被忽略但仍将使所有阻止失败的错误。因此,|| :一种忽略命令的解决方案。但这不是跨平台(Windows有没有|| :|| true
保罗-AG

Answers:


14

Makefile规则中的每个更新命令都在单独的Shell中执行。那么$?不包含上一个失败命令的退出状态,它包含$的默认值是什么?在新的外壳中。这就是为什么您的[$?-eq 0]测试始终成功。


10

您无需进行测试,$?因为&&if $?是否为零,并且||在返回值非零的情况下继续进行。

而且您不需要减号,因为返回值取自该行的最后一个继续程序调用。所以这很好

失败:

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

成功:

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

相反的情况是:如果您想编写自己的消息,并且想用非零值来破坏制作过程,则需要编写如下代码:

失败:

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

8

GNU make文档

当由于'-'或'-i'标志而导致错误被忽略时,make会像成功一样对待错误返回,不同之处在于它会输出一条消息,告诉您退出shell的状态代码,并且说该错误已被忽略。

make在这种情况下利用的退出状态,请make从脚本执行:

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

并让您的Makefile包含:

all:
    /bin/false
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.