【问题标题】:Gnu make: Run shell command and use exit code to set global variableGnu make:运行shell命令并使用退出代码设置全局变量
【发布时间】:2020-08-13 12:42:34
【问题描述】:

我有一个复杂的脚本c.sh 来测试机器make 运行的环境的某些部分。它应该使用bash 运行。它会打印一些有用的信息以供stdoutstderr 使用。如果满足某些特殊条件,则c.sh 存在,退出代码为 1,否则为 0。如果出现问题,可能会出现其他退出代码。根据退出代码,我想执行不同的配方。

all:
    # test using c.sh

everything-OK: # prerequisites
    # *recurse* on this if c.sh exits with zero
    # e.g. "$(MAKE) everything-OK" in all if ...

something-went-wrong: # prerequisites
    # *recurse* on this if c.sh exists with anything else

我找到了this 有用的答案,但它并没有太大帮助。由于我似乎无法使递归工作或 if 开关取决于退出代码。使用 $(.SHELLSTATUS) 起初看起来很有希望,但该解决方案不会立即从脚本重定向 stdout

另一种解决方案可能如下所示:

EVERYTHING_OK = 0 # 0: false, 1: true

all:
    # test using c.sh
    # set EVERYTHING_OK depending on exit code
    $(MAKE) second-stage

ifeq (1,EVERYTHING_OK)
second-stage: # prerequisites
    # ...
else
second-stage: # prerequisites
    # ...
endif

(我更喜欢这个,因为我可以将 if 条件放在宏中)

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    如果您只对脚本的退出状态感兴趣,最简单的方法可能是在 make 变量中捕获它并在 make 条件或目标名称中使用它。目标名称示例:

    C_EXIT_STATUS := $(shell ./c.sh &> /dev/null; echo $$?)
    
    .PHONY: all everithing-%
    
    all: everything-$(C_EXIT_STATUS)
    
    everything-0:
        @echo "all right"
    
    everything-%:
        @echo "not all right ($*)"
    

    然后,如果./c.sh 以状态 0 退出:

    $ make all
    all right
    

    如果它以状态 7 退出:

    $ make all
    not all right (7)
    

    make 条件示例:

    C_EXIT_STATUS := $(shell ./c.sh &> /dev/null; echo $$?)
    
    .PHONY: all
    
    ifeq ($(C_EXIT_STATUS),0)
    all:
        @echo "all right"
    else
    all:
        @echo "not all right ($(C_EXIT_STATUS))"
    endif
    

    最后但同样重要的是,正如您自己建议的那样,递归 make 也是一种选择:

    .PHONY: all
    
    ifeq ($(C_EXIT_STATUS),)
    all:
        s=0; ./c.sh &> /dev/null || s=$$?; \
        $(MAKE) C_EXIT_STATUS=$$s
    else ifeq ($(C_EXIT_STATUS),0)
    all:
        @echo "all right"
    else
    all:
        @echo "not all right ($(C_EXIT_STATUS))"
    endif
    

    【讨论】:

    • 我是否也可以使用1>&2 而不是&> 将调用的输出重定向到c.sh
    • 您是否尝试捕获标准输出 make 变量中的退出状态?
    • 我希望标准输出(和 -err)保持可见,因为它包含错误信息。我已经对此进行了测试,它可以按预期工作。
    • 啊,好的,我明白了。是的,绝对可以,您可以将stdout 重定向到stderr 并保留stdout 以获取退出状态。
    猜你喜欢
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    相关资源
    最近更新 更多