问题描述
说我有以下文件:
buggy_program:
buggy_program:
#!/bin/sh
echo "wops, some bug made me exit with failure"
exit 1
Makefile:
file.gz:
buggy_program | gzip -9 -c >$@
现在,如果我键入make
,即使buggy_program
以非零状态退出,GNU make也会愉快地构建file.gz
.
Now if I type make
, GNU make will happily build file.gz
even though buggy_program
exited with non-zero status.
在bash中,如果管道中的至少一个程序因故障而退出,则我可以执行set -o pipefail
使管道因故障而退出. GNU make中有类似的方法吗?还是一些不涉及临时文件的解决方法? (此处进行gzip压缩的原因恰恰是为了避免庞大的临时文件.)
In bash I could do set -o pipefail
to make a pipeline exit with failure if at least one program in the pipeline exits with failure. Is there a similar method in GNU make? Or some workaround that doesn't involve temporary files? (The reason for gzipping here is precisely to avoid a huge temporary file.)
推荐答案
这是不需要bash的可能解决方案.假设您有两个程序thisworks
和thisfails
分别失败或运行良好.然后,以下内容将只留下work.gz
,删除fail.gz
,即.当且仅当程序正确执行时,才创建gzip压缩的make目标:
Here's a possible solution that doesn't require bash. Imagine you have two programs thisworks
and thisfails
that fail or work fine, respectively. Then the following will only leave you with work.gz
, deleting fail.gz
, ie. create the gzipped make target if and only if the program executed correctly:
all: fail.gz work.gz
work.gz:
( thisworks && touch [email protected] ) | gzip -c -9 >$@
rm [email protected] || rm $@
fail.gz:
( thisfails && touch [email protected] ) | gzip -c -9 >$@
rm [email protected] || rm $@
说明:
在work.gz
规则的第一行中,thisworks
将成功退出,并且将创建文件work.gz.ok
,并且所有stdout都会通过gzip进入work.gz
.然后在第二行中,因为存在work.gz.ok
,所以第一个rm
命令也会成功退出-并且由于||
是短路,第二个rm
无法运行,因此不会删除work.gz
.
In the first line of the work.gz
rule, thisworks
will exit with success, and a file work.gz.ok
will be created, and all stdout goes through gzip into work.gz
. Then in the second line, because work.gz.ok
exists, the first rm
command also exits with success – and since ||
is short-circuiting, the second rm
does not get run and so work.gz
is not deleted.
OTOH,在fail.gz
规则的第一行中,thisfails
将失败退出,而fail.gz.ok
将不创建.所有的stdout仍然通过gzip进入fail.gz
.然后在第二行中,由于fail.gz.ok
不存在 ,因此第一个rm
命令失败退出,因此||
尝试第二个rm
命令删除fail.gz
文件.
OTOH, in the first line of the fail.gz
rule, thisfails
will exit with failure, and fail.gz.ok
will not be created. All stdout still goes through gzip into fail.gz
. Then in the second line, because fail.gz.ok
does not exist, the first rm
command exits with failure, so ||
tries the second rm
command which deletes the fail.gz
file.
要轻松检查其是否正常运行,只需分别用命令true
和false
替换thisworks
和thisfails
,将其放入Makefile中并键入make
.
To easily check that this works as it should, simply replace thisworks
and thisfails
with the commands true
and false
, respectively, put it in a Makefile and type make
.
(感谢#autotools中的友善帮助我.)
(Thanks to the kind people in #autotools for helping me with this.)
这篇关于等价于GNU make中的pipefail?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!