Shell make中的外壳状态代码

Shell make中的外壳状态代码,shell,makefile,Shell,Makefile,在重构Python脚本时,我使用一个Makefile(在Linux下运行GNU make)来自动化我的繁重工作。 脚本创建了一个输出文件,我希望确保在重构过程中输出文件保持不变 但是,我发现没有办法获取命令的状态代码来影响后续的shell if命令 以下规则说明了该问题: check-cond-codes: diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$

在重构Python脚本时,我使用一个Makefile(在Linux下运行GNU make)来自动化我的繁重工作。 脚本创建了一个输出文件,我希望确保在重构过程中输出文件保持不变

但是,我发现没有办法获取命令的状态代码来影响后续的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中内联编写所有命令是不可取的,但我将使用它作为最后手段

相关的:


使用“$$?”而不是“$$!”(感谢的第4个答案)

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

试试“\$?”,我认为$$是由makefile解释的。别忘了,您的每个命令都在单独的子shell中运行

这就是为什么你经常看到这样的事情:

my_target:
    do something \
    do something else \
    do last thing.
在调试时,不要忘记每个有用的-n选项,它将打印命令但不执行命令,还有-p选项,它将向您显示完整的make环境,包括各种位和块的设置位置


干杯,

我想您正在寻找
$?
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

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

如果要将结果代码传递给
If
,只需执行以下操作:

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

$$的动机很有用。普通
diff foo.txt foo.txt&&echo“无差异”
看起来更苗条:)注意:我观察到
echo$$原因$$?在echo之后变为0,可能是因为echo成功了。这导致我的if语句始终为true,以确认我测试了
echo$$?;echo$$在errorlevel=1的情况下,它会回显1,然后0@SketchBookGames当然是这样,因为
echo
的退出状态为零。我找不到任何关于
$$的信息在您提供的链接中。您可以通过修改URL更加具体,并使用第四个答案下方的
share
链接,根据流程退出代码给出直接指向退出Shell脚本第四个答案的URL,如果它仍然位于第四个位置,为什么这不是可接受的答案?2天前,Original poster@Omer Zak处于活动状态。虽然它不提供复制粘贴答案,但它确实准确地显示了解决问题所需的技术(多行Bash)。我认为您正在寻找
.SHELLSTATUS
变量: