我知道在Makefile中,使用
@
前缀可以阻止来自shell命令的输出,同时使用-
前缀可以忽略shell命令产生的错误。是否有一种方法可以将两者结合起来,即使用一个前缀既可以阻止输出又可以忽略错误?我认为@-
或者-@
并不起作用。实际上,@-
和-@
都可以工作,但会打印出一个make: [target] Error 1 (ignored)
警告。
相反,您可以使用
@command || true
或者,因为在shell中:
是true
的缩写,所以
@command ||:
通常这样做会更好,因为它避免了Make发出混淆的警告:忽略了一个不可见命令中的错误。
考虑两种最常见的情况,你可能想忽略命令的返回值:
对于第二种情况,请考虑在命令产生的日志文件中搜索警告的示例。如果grep
没有找到匹配项,它将返回错误,这并不是你想要的:
.PHONY: all one two three
all: at-warning at-success or-success or-warning
at-%: %.log
@echo Making $@
@-grep ^Warning $<
or-%: %.log
@echo Making $@
@grep ^Warning $< ||:
success.log:
echo 'Success!' > $@
warning.log:
echo 'Warning: foo' > $@
clean::
rm -f {success,warning.log}
输出:
echo 'Warning: foo' > warning.log
Making at-warning
Warning: foo
Making at-success
make: [at-success] Error 1 (ignored)
Making or-success
Making or-warning
Warning: foo
使用@-
会在成功时产生一个毫无意义的被忽略的错误警告,而|| true
则可以处理警告和没有警告的情况而不报错。
从理论上讲,使用|| true
比使用@-
要慢,但是这种额外开销在设计良好、维护良好的构建系统中不太可能成为瓶颈。大多数时间应该花在构建或检查时间戳上,当没有东西需要构建时,不是在运行成千上万个快速命令,所有这些命令的返回值都被忽略,这才会对性能产生可测量的影响。
GNU make允许您同时使用@
和-
:
all:
@-exit 1
使用 gmake 3.81 运行会产生以下输出:
gmake: [all] Error 1 (ignored)
正如你所看到的,命令没有被回显,错误也按预期被忽略了。
@-
和-@
都可以正常工作。同样适用于+
修饰符。 - Eldar Abusalimov