本文介绍了等价于GNU make中的pipefail?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下文件:

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的可能解决方案.假设您有两个程序thisworksthisfails分别失败或运行良好.然后,以下内容将只留下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.

要轻松检查其是否正常运行,只需分别用命令truefalse替换thisworksthisfails,将其放入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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-26 12:09