将 shell 输出分配给变量或退出(终止生成文件)



如果 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变量

首先,回答额外的问题。 这条线显然是错误的;我假设您刚刚遇到了剪切/粘贴错误:

HELPER := $(shell dirname $(abspath $(lastword 

我不知道你为什么要在这里突破壳并运行它的dirname但无论如何。

其次,这是来自您的帮助程序脚本:

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

根本不做你想要的:它说"将输出发送到文件描述符 2 (stderr( 并将其管道传输到/dev/stderr. 由于echo不打印任何内容来 stderr,这基本上是无操作的。 您似乎想要将标准输出(文件描述符 1(重定向到 stderr;那就是:

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

尽管更正确和可移植的编写方法是:

echo "[MAKE] $1" 1>&2

将 FD1 设置为写入 FD2 正在写入的任何位置。

现在进入你的真正问题:make没有像||&&这样的 shell 运算符的概念,所以在这里:

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

||等被简单地视为文本;它VERSION设置为字符串:

<whatever `shell`prints> ||  (echo "getVersion failed '$$?' status"; exit 1)

这正是你所看到的。

如果你有一个足够新的 GNU make 版本(4.2 或更高版本(,你可以使用.SHELLSTATUS变量来找出最后一个 shell 的退出状态。 然后你可以做这样的事情:

.SHELLSTATUS = 0
VERSION ?= $(shell . $(HELPER); getVersion)
$(if $(filter-out 0,$(.SHELLSTATUS)),$(error getVersion failed '$(.SHELLSTATUS)' status))

(您必须先设置它,因为您在此处使用?=因此有时不会调用 shell 函数(。

如果你需要移植到早期版本的GNU make,或者你只是喜欢使用更清晰的东西,你可以检查VARIABLE的值。 如果您更改脚本,以便它将错误写入 stderr,并且在失败时不向 stdout 写入任何内容,您可以使用:

VERSION ?= $(shell . $(HELPER); getVersion)
$(if $(VERSION),,$(error getVersion failed))

最新更新