如何反转Makefile中的错误代码

如何反转Makefile中的错误代码

我想测试文件是否包含模式(跳过茉莉花测试,当从 travis 运行时,它会使我的构建失败)。

我有这样的代码:

skipped_tests:
    $(if $(shell grep -E 'iit|ddescribe' spec/terminalSpec.js), @false, @true)

grep问题是,当它找到与模式匹配的行时,我没有得到输出。我想要这个,这样我就可以在 travis 构建日志中看到哪一行导致了问题。有没有办法反转命令错误代码(返回非 0 时返回 0,反之亦然)?

我也尝试过这个:

skipped_tests:
    grep -E 'iit|ddescribe' spec/terminalSpec.js
    @test $$? -eq 0 # should it be -ne

但这会回显已经失败且未失败的一行iit,如果找不到该行,则 grep 会失败。

答案1

这个怎么样?

skipped_tests:
    @! grep -E 'iit|ddescribe' spec/terminalSpec.js

答案2

我通过调用 grep 两次解决了这个问题

skipped_tests:
    @grep -E 'iit|ddescribe' spec/terminalSpec.js || true
    $(if $(shell grep -E 'iit|ddescribe' spec/terminalSpec.js), @false, @true)

有没有更好的办法?

我尝试了一些其他的东西,但似乎 make 正在对字符串进行操作(在 Makefile 上使用 str.replace 或其他东西),因为如果 grep 的输出是源代码行,它会从其他可能的解决方案中给出语法错误。

答案3

可能的解决方案:

在顶部定义变量Makefile并使用ifeq.例如:

RESULT = $(shell grep ... 2>/dev/null && echo 0 || echo 1)
. . .
skipped_tests:
ifeq ($(RESULT),0)
    . . .
endif

但即使skipped_tests 没有调用,grep也会在每次调用时执行。make如果每次都调用该目标,那么它也是解决方案。


考虑到你的意愿。如果您想grep多次使用目标中的结果,可以使用多行表达式。假设我有下一个Makefile

all: target

target:
    @res=`grep -E 'test|pttern' test.js` || { res="" ; : ; } ; \
        [ ! -z "$$res" ] && echo "Grep result: $$res" ; \
        ls ; \
        [ ! -z "$$res" ] && echo "Grep result: $$res" ; \
    :

.PHONY: target

test.js在同一目录中有下一个:

$ cat test.js
pattern

如果模式不匹配,则会出现下一个结果:

$ make
Makefile  test.js

如果模式存在,将会出现下一个结果:

$ make
Grep result: pattern
Makefile  test.js
Grep result: pattern

为了便于阅读,您可以``使用进行更改res=$$(grep -E ...) || ...

当然,在一次系统调用中发出多行命令并不是很方便(多行是解释器的一个会话),但有时在您需要操作一个变量(也是环境变量)的情况下可能很有用。

相关内容