Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Makefile gnumake:运行shell命令并使用退出代码设置全局变量_Makefile_Gnu Make - Fatal编程技术网

Makefile gnumake:运行shell命令并使用退出代码设置全局变量

Makefile gnumake:运行shell命令并使用退出代码设置全局变量,makefile,gnu-make,Makefile,Gnu Make,我有一个复杂的脚本c.sh,它测试机器运行环境的某些部分。它应该使用bash运行。它会打印一些有用的信息,供stdout和stderr使用。如果满足某些特殊条件,c.sh存在,退出代码为1,否则为0。如果出现问题,可能会出现其他退出代码。根据退出代码,我希望执行不同的配方 all: # test using c.sh everything-OK: # prerequisites # *recurse* on this if c.sh exits with zero #

我有一个复杂的脚本
c.sh
,它测试机器运行环境的某些部分。它应该使用
bash
运行。它会打印一些有用的信息,供
stdout
stderr
使用。如果满足某些特殊条件,
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
我已经找到了有用的答案,但并没有多大帮助。因为我似乎无法根据退出代码使递归或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条件放在宏中)

如果您只对脚本的退出状态感兴趣,最简单的方法可能是在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 ($*)"
然后,如果退出状态为0的
/c.sh

$ 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
最后但并非最不重要的一点是,正如您自己所建议的,递归生成也是一个选项:

.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变量中捕获标准输出和退出状态?我希望stdout(和-err)保持可见,因为它包含错误信息。我已经测试过了,它能正常工作。啊,好的,我明白了。是的,绝对可以,您可以将
stdout
重定向到
stderr
,并保留
stdout
作为退出状态。