无法捕获makefile中的命令退出代码

时间:2019-07-11 19:27:44

标签: bash makefile

我正在尝试设置我的第一个makefile,并在步骤1中遇到一个障碍。在我的shell脚本中,我这样做是

which brew | grep 'brew not found' >/dev/null 2>&1
if [ $? == 0 ]; then
    xcode-select --install
    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
fi

这作为bash脚本很好用。经过一番谷歌搜索之后,对于Makefile,到目前为止,我已经提出了以下命令:

BREW_INSTALLED = $(shell which brew | grep 'brew not found' >/dev/null 2>&1; echo $$?)

但是,运行它会吸引我

make: BREW_INSTALLED: No such file or directory

我同样不确定何时将@添加到命令中(好像什么我不想输出的东西一样。)。

我目前在GNU Make 3.81上。

2 个答案:

答案 0 :(得分:4)

典型的makefile会检查所需工具的存在,例如:

BREW := $(shell which brew)

# Check if variable brew is empty
ifeq ($(BREW),)
    $(error brew not found)
else
    $(info brew found: $(BREW))
endif


all:
    @echo "Do something with brew"
    $(BREW) --version

注意:前两行缩进的行中不能有制表符。 如果必须使用制表符将 all Rule 缩进,则两条 Recipe 行。


食谱开头的@会回显:https://www.gnu.org/software/make/manual/html_node/Echoing.html

答案 1 :(得分:4)

这一行有很多可能性:

BREW_INSTALLED = $(shell which brew | grep 'brew not found' >/dev/null 2>&1; echo $$?)

如果成功,则哪个将其输出写入stdout,以防stderr失败。您正在尝试在stdout上捕获错误消息。

要将哪个的标准输入到 grep ,您需要编写

which brew 2>&1 >/dev/null | grep 'brew not found'

2>&1>的顺序也很重要)。

但是您不应该依赖 which 的特定错误消息。


但是您已经从哪个获取了所需的返回码,因此根本不需要grep。

  

返回失败参数的数量,或者当没有给出“程序名”时返回-1。   https://linux.die.net/man/1/which


考虑使用grep -q 'expression'抑制输出,而不是重定向stdout和stderr。

  

-q,--quiet,--silent

     

安静;不要在标准输出中写任何东西。如果发现任何匹配项,即使检测到错误,也以零状态立即退出。   https://linux.die.net/man/1/grep


您收到的错误消息与我在上面写的内容无关。这意味着shell试图以命令的形式运行 BREW_INSTALLED ,这可能意味着 make 将其放置在新shell的开头。 也许您在制表符之后写了它?参见https://www.gnu.org/software/make/manual/html_node/Recipe-Syntax.html


要捕获返回代码(作为字符串!):

BREW_INSTALLED := $(shell which brew >/dev/null 2>&1; echo $$?)