在makefile中捕获shell的标准错误

3
我在 makefile 中的 shell function 遇到了问题。做法如下:
var := $(shell some-command)

允许我捕获 some-commandstdout
这样做:
var := $(shell some-command 2>&1)

允许我捕获 some-commandstdoutstderr
如何捕获 shell 本身的 stderr
这个 makefile 演示了问题:
var1 := $(shell date 2>&1)
var2 := $(shell ls aaa 2>&1)
var3 := $(shell a-command-which-does-not-exist 2>&1)

show-me:
    @echo var1: \"$(var1)\"
    @echo var2: \"$(var2)\"
    @echo var3: \"$(var3)\"

它会产生:
/bin/sh: 1: a-command-which-does-not-exist: not found
var1: "So 6. Feb 00:37:05 CET 2022"
var2: "ls: cannot access aaa: No such file or directory"
var3: ""

我想将 /bin/sh: 1: a-command-which-does-not-exist: not found 捕获到变量 var3 中,这可能吗?
1个回答

3

你需要在子Shell中运行它:

var3 := $(shell $(SHELL) -c 'a-command-which-does-not-exist' 2>&1)

很遗憾,没有其他方法。

预计完成时间 好的,我弄清楚了。问题在于,如果由$(shell ...)函数调用的shell以错误代码127退出(这是当shell找不到要运行的程序时shell的退出代码),那么GNU make将明确地将其输出写入stderr而不是捕获它(如果您检查function.c:func_shell_base()函数,您将看到这一点)。

您调用的shell发生任何可以确保它不以127退出代码退出的更改都将“解决”问题:

$ cat Makefile
out := $(shell bad-program 2>&1 || exit 1)
$(info out = $out)

$ make
out = /bin/sh: 1: bad-program: not found
make: *** No targets.  Stop.

这可能是GNU make中的一个bug。我需要考虑一下。


谢谢。我不知道你测试的是哪个版本的make,但对我来说不起作用...我已经尝试过在命令内部和外部重定向,结果相同:stderr未被捕获。你发布的版本在逻辑上似乎是正确的,但对我来说不起作用(GNU Make 4.2.1)。 - blueFast
不好意思,我的例子是错的。问题在于打印错误的不是命令本身,因此重定向命令的输出是没有用的。是 shell 打印了错误,所以你需要重定向 shell 的输出:应该是 $(shell $(SHELL) -c bad-command 2>&1)。然而,这也不起作用,我不确定为什么……嗯…… - MadScientist
我上面的评论是错误的 :) - MadScientist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接