相当于GNU make中的pipefail?

unh*_*mer 17 makefile pipe

说我有以下文件:

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)

  • 请注意,这将影响文件中的每个规则.即便是那些. (4认同)
  • 是否可以使用“/usr/bin/env”来执行此操作? (2认同)

unh*_*mer 7

这是一个不需要bash的可能解决方案.想象一下,你有两个项目thisworksthisfails失败或分别做工精细.然后以下只会留下你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文件.


为了方便地查看这个工程,因为它应该,只需更换thisworksthisfails与命令truefalse分别,把它放在一个Makefile和类型make.

(感谢#autotools中善良的人帮助我解决这个问题.)


man*_*lio 5

你可以这样做:

SHELL=/bin/bash

.DELETE_ON_ERROR:
file.gz:
    set -o pipefail; buggy_program | gzip -9 -c >$@
Run Code Online (Sandbox Code Playgroud)

这只适用于bash.