make中的Shell状态代码

时间:2009-04-14 16:48:26

标签: shell makefile

我使用Makefile(在Linux下运行GNU make)在重构Python脚本时自动完成我的工作。 该脚本创建了一个输出文件,我想确保输出文件在重构时保持不变。

但是,我发现无法获取命令的状态代码以影响后续shell if命令。

以下规则说明了问题:

check-cond-codes:
    diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$$!=
    diff -q poalim report2008_4.csv; echo differences: =$$!=

第一个'diff'比较两个相同的文件,第二个比较两个不同的文件。 输出是:

diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$!=
no differences: ==
diff -q poalim report2008_4.csv; echo differences: =$!=
Files poalim and report2008_4.csv differ
differences: ==

显然'$$!'是捕获'diff'状态代码的错误变量。 即使使用     SHELL:= / bin / bash 在Makefile的开头没有解决问题。

返回我需要的值的变量(如果它存在的话)将在真实规则中的'if'命令中使用。

创建一个小的ad-hoc shell脚本代替在Makefile中内联编写所有命令的替代方法是不可取的,但我会将它作为最后的手段使用。

相关:

6 个答案:

答案 0 :(得分:36)

我认为你正在寻找$? shell变量,它给出了上一个命令的退出代码。例如:

$ diff foo.txt foo.txt
$ echo $?
0

要在你的makefile中使用它,你必须逃避$,就像在$$?中一样:

all:
    diff foo.txt foo.txt ; if [ $$? -eq 0 ] ; then echo "no differences" ; fi

请注意,make中规则主体中的每个命令都在一个单独的子shell中运行。例如,以下内容不起作用:

all:
    diff foo.txt foo.txt
    if [ $$? -eq 0 ] ; then echo "no differences" ; fi

因为diffif命令在不同的shell进程中执行。如果要使用命令中的输出状态,则必须在同一shell的上下文中执行此操作,如在前面的示例中所示。

答案 1 :(得分:4)

使用'$$?'而不是'$$!' (感谢Exit Shell Script Based on Process Exit Code)的第4个答案

答案 2 :(得分:3)

不要忘记您的每个命令都在不同的子shell中运行。

这就是为什么你经常会看到类似的东西:

my_target:
    do something \
    do something else \
    do last thing.

在调试时,不要忘记每个有用的-n选项,它将打印命令但不执行它们,-p选项将显示完整的make环境,包括设置各种位和的位置。

HTH

欢呼声,

答案 3 :(得分:2)

如果您将结果代码传递给if,则可以执行以下操作:

all:
    if diff foo.txt foo.txt ; then echo "no differences" ; fi

答案 4 :(得分:0)

bash变量是$?,但为什么还要打印状态代码?

答案 5 :(得分:-4)

试试`\ $?'我认为$$正在被makefile解释