为什么[...]语法在`test`不能在Makefile中起作用? [英] Why [ ... ] syntax doesn't work in a Makefile while `test` does?

查看:225
本文介绍了为什么[...]语法在`test`不能在Makefile中起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux Mint 19上.我对Makefiles完全陌生.

I am on Linux Mint 19. I am entirely new to Makefiles.

这是有问题的部分:

[ $(shell id --user) -eq 0 ] && ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 )

会引发此错误:

[ 1000 -eq 0 ] && ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 )
Makefile:25: recipe for target 'distrib' failed
make: *** [distrib] Error 1


相反,直接使用test命令被证明可以完全正常工作:


On the contrary, using test command directly proves to be working entirely:

if test $(shell id --user) -eq 0; then ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 ) fi

我想问为什么,我违反了一些Makefile规则吗?

I want to ask why that is, did I break some Makefile rule?

推荐答案

这与makefile没有任何关系,它与shell脚本以及使用&&if的区别退出代码.您正在这里比较苹果和桔子.

This doesn't have anything to do with makefiles, it has to do with shell scripting and the difference between using && vs. if in terms of the exit code. You are comparing apples and oranges here.

test[无关.如果在if语句中使用[编写版本,则将获得与test相同的行为,并且如果使用&&模型编写test版本,则将获得行为与[相同.

It's not related to test vs [. If you write the version using [ inside an if statement you'll get the same behavior as you do with test, and if you write the test version with the && model you'll get the same behavior as you do with [.

在您的shell中运行它:

Run this in your shell:

[ 1000 -eq 0 ] && echo hi
echo $?

现在在您的shell中运行它:

Now run this in your shell:

if [ 1000 -eq 0 ]; then echo hi; fi
echo $?

您将看到前者给出了非0的退出代码,而后者给出了0(成功)的退出代码.这就是if的工作方式;它吞噬"该条件的退出代码.

You'll see the former gives a non-0 exit code, while the latter gives a 0 (success) exit code. That's how if works; it "swallows" the exit code of the condition.

Make总是查看shell脚本的退出代码来确定它是否失败.

Make always looks at the exit code of the shell script to decide if it failed or not.

通常在make脚本中,您要重新排列表达式以使用||而不是&&.这样可以确保如果脚本提前退出,则会以成功代码而不是失败代码退出.您可以这样编写脚本:

Generally in make scripting you want to re-arrange your expressions to use || rather than &&. That ensures that if the script exits early it exits with a success code not a failure code. You can write your script like this:

[ $$(id -u) -ne 0 ] || ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 )

请注意,我使用的是$$(id -u)而不是$(shell id --user);配方已经在外壳中运行,并且在配方中使用make shell函数是一种反模式.另外,-u选项是POSIX标准选项,而--user仅在id的GNU实用程序版本中可用.

Note I use $$(id -u) not $(shell id --user); the recipe is run in the shell already and it's an anti-pattern to use the make shell function in a recipe. Also, the -u option is a POSIX standard option while --user is only available in the GNU utilities version of id.

这篇关于为什么[...]语法在`test`不能在Makefile中起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆