首页 > 解决方案 > Makefile 检查命令块是否成功

问题描述

我有一个这样的目标:

.PHONY: do-symlink
do-symlink:
    ln -s $(HERE_ONE_FILE) $(THERE_ONE_DIR)/
    ln -s $(HERE_TWO_FILE) $(THERE_ONE_DIR)/

    # check if those succeed or failed. I want to make sure both have passed
    if succeeded:
        do_something
    else:
        do_something_else

我如何检查它们是否都成功?如果是这样,基于它做些什么?

标签: makefile

解决方案


所以首先,如果一个 make recipe 行失败,make 失败,并停止执行这个 recipe。因此,如果您将配方行放在末尾@echo "succeeded",那么如果之前的所有行都有效,这将运行。至于打印失败的特定内容,您可以使用||bash

all:
   @command1 || { echo "command1 failed"; exit 1 }
   @command2 || { echo "command2 failed"; exit 1 }
   @echo "command1 and command2 passed"

注意exit 1里面的'。通常,false || echo "false"返回状态为0(pass),因为退出状态取自最后一个命令运行 ( echo "false"),它将始终成功。这将导致 make 始终继续运行下一个配方行。您可能希望这样做,但是,您可以通过复合语句并在最后执行 an 来保留失败exit 1

无论退出状态如何都运行这两个命令,然后在之后处理退出,请在配方行前加上-. 如果命令失败,这将导致 make 不会停止运行。但是请注意,每个配方行都在其自己的 shell 中运行,因此一个配方行不能直接访问另一行的返回代码。您可以输出到一个文件,然后在后面的配方行中访问该文件:

 all:
     -@command1; echo $? > .commands.result
     -@command2; echo $? >> .commands.result
     @if grep -q "^00$" .commands.result; then \
            echo both commands passed; \
     else \
            echo "at least one command failed"

(或者您总是可以将所有食谱行连接成一个 bash 命令并传递变量)。


推荐阅读