将shell输出分配给变量或退出(终止makefile)

时间:2018-06-21 00:18:39

标签: bash makefile

如果shell命令输出$$,如何以错误终止Makefile? -ne 0吗?

HELPER := $(shell dirname $(abspath $(lastword 
VERSION ?= $(shell . $(HELPER); getVersion) ||  (echo "getVersion failed '$$?' status"; exit 1)

test:
        @echo "What is going on?$(VERSION) ?"

helper.sh:

#!/bin/bash
printError() {
    echo "[MAKE] $1" 2>/dev/stderr
}
getVersion() {
    version=$(git describe --exact-match --tags $(git log -n1 --pretty='%h') 2>/dev/null)
    if [ $? -ne 0 ]; then
        printError "Getting git tag for version failed. Checkout existing tag or"
        printError "provide your own version 'make <action> VERSION=<your-version>'"
        exit 1
    fi
    echo "${version}"
    exit 0
}

输出:

$ make test
What is going on?[MAKE] Getting git tag for version failed. Checkout existing tag or [MAKE] provide your own version 'make <action> VERSION=<your-version>' ||  (echo getVersion failed $? status; exit 1) ?

我无法在出错时终止它(getVersion返回1),但是通过管道传递到/dev/stderr的错误消息也正在到达VERSION变量

1 个答案:

答案 0 :(得分:1)

首先,回答其他问题。这行显然是错误的。我想你只是有一个剪切/粘贴错误:

I/Choreographer: Skipped 51 frames!  The application may be doing too much work on its main thread.

我不知道您为什么在这里使用shell并运行其HELPER := $(shell dirname $(abspath $(lastword ,但无论如何。

第二,这来自您的帮助脚本:

dirname

根本不执行您想要的操作:它说“将输出传递到文件描述符2(stderr),并将其通过管道传递到echo "[MAKE] $1" 2>/dev/stderr 。由于/dev/stderr不会打印任何内容来stderr基本上是无操作的操作,您似乎想将stdout(文件描述符1)重定向到stderr;这就是这样:

echo

尽管更正确,更可移植的书写方式是:

echo "[MAKE] $1" >/dev/stderr

将fd1设置为写入fd2正在写入的位置。

现在继续您的真实问题:echo "[MAKE] $1" 1>&2 没有像make||这样的shell运算符的概念,所以在这里:

&&

VERSION ?= $(shell . $(HELPER); getVersion) || (echo "getVersion failed '$$?' status"; exit 1) 等被简单地视为文本;它将||设置为字符串:

VERSION

这就是您所看到的。

如果您使用的是新版本的GNU make(4.2或更高版本),则可以使用 <whatever `shell`prints> || (echo "getVersion failed '$$?' status"; exit 1) 变量来查找最后一个shell的退出状态。然后您可以执行以下操作:

.SHELLSTATUS

(您必须先设置它,因为在这里使用.SHELLSTATUS = 0 VERSION ?= $(shell . $(HELPER); getVersion) $(if $(filter-out 0,$(.SHELLSTATUS)),$(error getVersion failed '$(.SHELLSTATUS)' status)) ,因此有时不会调用任何shell函数)。

如果您需要移植到GNU make的早期版本,或者只想使用更清晰的名称,则可以检查?=的值。如果您更改脚本,以至于它在stderr中写入错误,而在失败时不向stdout写入任何内容,则可以使用:

VARIABLE