如果文件不存在,有没有办法退出并出现错误?我目前正在做这样的事情:
all: foo
foo:
test -s /opt/local/bin/gsort || echo "GNU sort does not exist! Exiting..." && exit
运行make
会运行all
目标,该目标会运行foo
。
期望是如果test -s
条件失败,则执行echo/exit
语句。
但是,即使存在/usr/bin/gsort
,我也会得到echo
语句的结果,但exit
命令不会运行。这与我希望完成的事情相反。
执行上述操作的正确方法是什么?
答案 0 :(得分:27)
我意识到这一点有点陈旧,但您甚至不需要使用子shell来测试Make中是否存在文件。
这还取决于您希望/期望它如何运行。
使用通配符函数,如下所示:
all: foo
foo:
ifeq (,$(wildcard /opt/local/bin/gsort))
$(error GNU Sort does not exist!)
endif
是一种很好的方法。请注意,ifeq子句不是缩进的,因为它是在目标本身之前计算的。
如果您希望无条件地为每个目标发生这种情况,您可以将其移出目标:
ifeq (,$(wildcard /opt/local/bin/gsort))
$(error GNU Sort does not exist!)
endif
答案 1 :(得分:18)
exit
单独返回执行的最后一个命令的状态。在这种情况下,它返回零,这意味着一切正常。
这是因为||
和&&
有equal precedence,而shell会将命令解释为已写入
( test ... || echo ... ) && exit
如果您想要发出失败信号,则必须以非零值退出,例如exit 1
。
如果你想回显和退出,只需按顺序将命令分隔为;
all: foo
foo:
test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
答案 2 :(得分:7)
make中的每个命令行都在自己的子shell中运行。因此,运行exit
只退出该子shell - 而不是整个makefile。默认情况下,如果任何子shell返回不成功的退出状态,make
执行将停止(按照惯例,0表示成功,因此其他任何内容都将停止执行)。最简单的方法就是使用test
命令的退出状态:
all: foo
foo:
test -s /opt/local/bin/gsort
打印诊断消息会使事情变得复杂,因为像echo
这样的命令将返回退出状态0,导致make
认为一切正常。要解决此问题,您需要在其后运行一个命令,使子shell具有非零退出状态:
all: foo
foo:
test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
甚至只是
all: foo
foo:
test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; false; }
答案 3 :(得分:2)
简单地说:
all: /opt/local/bin/gsort
如果缺少/opt/local/bin/gsort
,您将无法制定目标`/ opt / local / bin / gsort'"错误信息。
但如果您还想要一些很好的解释:
/opt/local/bin/gsort:
echo "GNU sort does not exist! Exiting..."
false
在GNU / Make中,如果未声明目标.PHONEY
并且没有任何依赖关系,则如果与该目标不匹配的文件不存在,则将调用该规则。
以上代码仅在false
不存在时触发/opt/local/bin/gsort
命令,返回非0值,make将失败。
答案 4 :(得分:2)
由于您正在检查是否存在gsort
可执行文件,因此您可以使用which
或type
shell命令,例如:
all: foo
:
foo:
which gsort || exit 1
# or
type gsort || exit 1
您不需要错误消息,因为它会自动打印:
/ bin / sh:第0行:输入:
gsort
:未找到
这很明显。
或者使用test
或[
(请参阅:help test
/ help [
获取语法),例如
test -x /opt/local/bin/gsort || { echo Error msg; exit 1; }
检查给定文件是否存在且可执行,否则显示消息并退出。通过对命令进行分组,括号对于覆盖运算符的正常优先级(从左到右)非常重要(有关详细信息,请参阅Compound Commands
中的man bash
部分)。
另一种方法是使用规则的目标来检查文件是否存在并添加为all
的依赖项,例如
all: /opt/local/bin/gsort
@echo Success.
/opt/local/bin/gsort:
@echo "GNU sort does not exist! Exiting..."
exit 1
结果:
$ make
GNU sort does not exist! Exiting...
exit 1
make: *** [/opt/local/bin/gsort] Error 1