说我有以下文件:
buggy_program:
#!/bin/sh
echo "wops, some bug made me exit with failure"
exit 1
Run Code Online (Sandbox Code Playgroud)
Makefile文件:
file.gz:
buggy_program | gzip -9 -c >$@
Run Code Online (Sandbox Code Playgroud)
现在如果我输入make,file.gz即使buggy_program退出非零状态,GNU make也会很乐意构建.
在bash中set -o pipefail,如果管道中至少有一个程序出现故障,我可以做一个失败的管道退出.GNU make中有类似的方法吗?或者一些不涉及临时文件的解决方法?(这里gzipping的原因正是为了避免一个巨大的临时文件.)
Qua*_*ong 21
试试这个
SHELL=/bin/bash -o pipefail
file.gz:
buggy_program | gzip -9 -c >$@
Run Code Online (Sandbox Code Playgroud)
这是一个不需要bash的可能解决方案.想象一下,你有两个项目thisworks和thisfails失败或分别做工精细.然后以下只会留下你work.gz,删除fail.gz,即.当且仅当程序正确执行时,创建gzipped make目标:
all: fail.gz work.gz
work.gz:
( thisworks && touch $@.ok ) | gzip -c -9 >$@
rm $@.ok || rm $@
fail.gz:
( thisfails && touch $@.ok ) | gzip -c -9 >$@
rm $@.ok || rm $@
Run Code Online (Sandbox Code Playgroud)
说明:
在work.gz规则的第一行,thisworks将成功退出,并将work.gz.ok创建一个文件,并且所有stdout都通过gzip进入work.gz.然后在第二行,因为work.gz.ok存在,第一个rm命令也会成功退出 - 并且由于||是短路,第二个命令rm 不会运行,因此work.gz不会被删除.
OTOH,在第一行fail.gz的规则,thisfails将与失败退出,fail.gz.ok将不会被创建.所有stdout仍然通过gzip进入fail.gz.然后,在第二行中,因为fail.gz.ok没有不存在,则第一rm命令退出故障,所以||尝试第二个rm,其删除该命令fail.gz文件.
为了方便地查看这个工程,因为它应该,只需更换thisworks并thisfails与命令true和false分别,把它放在一个Makefile和类型make.
(感谢#autotools中善良的人帮助我解决这个问题.)
你可以这样做:
SHELL=/bin/bash
.DELETE_ON_ERROR:
file.gz:
set -o pipefail; buggy_program | gzip -9 -c >$@
Run Code Online (Sandbox Code Playgroud)
但这只适用于bash.
| 归档时间: |
|
| 查看次数: |
3029 次 |
| 最近记录: |