Error handling 如何在Makefile中设置pipefail

Error handling 如何在Makefile中设置pipefail,error-handling,makefile,pipe,Error Handling,Makefile,Pipe,考虑这个文件: all: test 1 -eq 2 | cat echo 'done' 它将毫无错误地执行 我听说过我可以这样使用的set-o pipefail: all: set -o pipefail; \ test 1 -eq 2 | cat; \ echo 'done' set -o pipefail && test 1 -eq 2 | cat && echo 'done' 除了不起作用外,这篇文

考虑这个文件:

all: 
    test 1 -eq 2 | cat
    echo 'done'
它将毫无错误地执行

我听说过我可以这样使用的
set-o pipefail

all: 
    set -o pipefail;     \
    test 1 -eq 2 | cat;  \
    echo 'done'
set -o pipefail && test 1 -eq 2 | cat && echo 'done'
除了不起作用外,这篇文章非常痛苦

另一个解决方案是使用临时文件。我想避免它


我还可以使用什么解决方案?

对于任何比单个命令更复杂的问题,我通常更喜欢使用脚本。通过这种方式,您可以完全控制解释器(通过),并且您可以将更复杂的命令放在一起,而不是试图将其有效地塞进一行。例如:

Makefile

all:
    ./my.sh
my.sh

#!/usr/bin/env bash
set -o errexit -o pipefail
test 1 -eq 2 | cat
echo 'done'
也就是说,像您拥有的Makefile命令块一样的退出代码是最后一个命令的退出代码,因为您使用
分隔命令
您可以使用
&
执行,直到出现错误(相当于
errexit
),如下所示:

all: 
    set -o pipefail;     \
    test 1 -eq 2 | cat;  \
    echo 'done'
set -o pipefail && test 1 -eq 2 | cat && echo 'done'

作为make的SHELL调用的一部分,可以强制pipefail打开 从


这可能是一个解决方案,但随后您将有几十个与Makefile相关的脚本。然后,我想知道你是如何组织它的。就像任何其他复杂的项目一样,你会想让复杂性变得易于管理。很多脚本做一件事通常比一个巨大的makefile更容易管理。你知道我可以从哪些好的GitHub项目中获得灵感吗?我有一些我在其他各种项目中使用的,但我会尽量让它尽可能简单。并确保在每一个可能的机会使用真实的语言而不是shell。代码可能会更长,但在可维护性和可测试性方面,您可以省去很多麻烦。这正是我的问题所在。今天,我重写了一个用Perl编写的脚本,该脚本通过在每个文件的末尾添加校验和来拆分文件,并将shell脚本嵌入到目标中。我尝试过Python,但它太慢了(大约比Perl慢5-10倍,有时比纯shell脚本慢。第二个代码段怎么不起作用?它应该可以正常工作(除了
cat
显然毫无意义之外)。或者您的意思是它不会阻止
done
被回送出去吗?它不会这样做,因为没有任何命令告诉shell停止执行。这里只有一行代码,不会成倍增加,因此make无法终止
测试
失败(即使它通过
|cat
)。放下
;`between
cat`和
echo
,它会做你所期望的。我的
GNU Make 4.1没有任何错误。你的示例代码不应该有任何错误。
test
失败只是被忽略了。没有任何东西会看它。你期望Make看到它并使配方失败,但这只发生在整个命令的返回代码(通常是一行,但在您的例子中是三行的连接集)。在我的用例中,我使用一个自制的cksum脚本,我将它导入
dd-of=$@-seek=$$($$(stat-c%s$@)-4))
。如果cksum失败,dd也应该失败,我不应该执行其余的命令。或者使用两行
set-o pipefail;\cksum…| dd…| | exit 1
echo done
,而不将它们合并在一起。谢谢。这可能是这里可以接受的答案。简短、简洁,通常适用于所有shell中
Makefile
中的职业。