Linux 如何获取 GNU Makefile 中使用的 shell 命令的退出状态?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16315089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:49:52  来源:igfitidea点击:

How to get exit status of a shell command used in GNU Makefile?

linuxshellmakefilegnu-make

提问by Lunar Mushrooms

I have a makefile rule in while I am executing a linux tool. I need to check the exit status of the tool command, and if that command fails the make has to be aborted.

我在执行 linux 工具时有一个 makefile 规则。我需要检查工具命令的退出状态,如果该命令失败,则必须中止 make。

I tried checking with $?, $$? \$? etc in the makefile. But they gives me syntax error when makefile runs.

我试着用 $?, $$? \$? makefile 中的等。但是当 makefile 运行时,它们给了我语法错误。

What is the right way to do this ?

这样做的正确方法是什么?

Here is the relevant rule in Makefile

这是Makefile中的相关规则

    mycommand \
    if [ $$? -ne 0 ]; \
    then \
        echo "mycommand failed"; \
        false; \
    fi
    mycommand \
    if [ $$? -ne 0 ]; \
    then \
        echo "mycommand failed"; \
        false; \
    fi

采纳答案by suspectus

In the makefile-:

在生成文件中-:

mycommand || (echo "mycommand failed $$?"; exit 1)

Each line in the makefile action invokes a new shell - the error must be checked in the action line where the command failed.

makefile 操作中的每一行都会调用一个新的 shell - 必须在命令失败的操作行中检查错误。

If mycommand fails the logic branches to the echo statement then exits.

如果 mycommand 失败,则逻辑分支到 echo 语句然后退出。

回答by c24w

Here are a couple of other approaches:

以下是其他几种方法:



shell& .SHELLSTATUS

shell& .SHELLSTATUS

some_recipe:
    @echo $(shell echo 'doing stuff'; exit 123)
    @echo 'command exited with $(.SHELLSTATUS)'
    @exit $(.SHELLSTATUS)

Output:

输出:

$ make some_recipe

doing stuff
command exited with 123      
make: *** [Makefile:4: some_recipe] Error 123

It does have the caveat that the shellcommand output isn't streamed, so you just end up with a dump to stdout when it finishes.

它确实有一个警告,即shell命令输出不是流式传输的,因此您只会在完成时转储到标准输出。



$?

$?

some_recipe:
    @echo 'doing stuff'; sh -c 'exit 123';\
    EXIT_CODE=$$?;\
    echo "command exited with $$EXIT_CODE";\
    exit $$EXIT_CODE

Or, a bit easier to read:

或者,更容易阅读:

.ONESHELL:

some_recipe:
    @echo 'doing stuff'; sh -c 'exit 123'
    @EXIT_CODE=$$?
    @echo "command exited with $$EXIT_CODE"
    @exit $$EXIT_CODE

Output:

输出:

$ make some_recipe

doing stuff                  
command exited with 123      
make: *** [Makefile:2: some_recipe] Error 123

It's essentially one string of commands, executed in the same shell.

它本质上是一串命令,在同一个 shell 中执行。

回答by reinierpost

If all you want is for the maketo be aborted iff the tool exits with a nonzero status, makewill already do that by default.

如果您想要的只是make中止,如果工具以非零状态退出,make则默认情况下已经这样做了。

Example Makefile:

示例Makefile

a: b
    @echo making $@
b:
    @echo making $@
    @false
    @echo already failed

. This is what happens with my make:

. 这就是我的情况make

$ make
making b
make: *** [Makefile:6: b] Error 1

Make sure partially or wholly created targets are removed in case you fail. For instance, this

确保在失败时删除部分或全部创建的目标。例如,这

a: b
    @gena $+ > $@
b:
    @genb > $@

is incorrect: if on the first try, genbfails, it will probably leave an incorrect b, which, on the second try, makewill assume is correct. So you need to do something like

不正确:如果第一次尝试genb失败,它可能会留下一个不正确的b,在第二次尝试时,它make会假设是正确的。所以你需要做类似的事情

a: b
    @gena $+ > $@ || { rm $@; exit 1; }
b:
    @genb > $@