为什么“git submodule add…”输出到stderr而不是stdout?

6

这条消息

Cloning into 'sub-mod'...
done.

在运行git submodule add...命令后,我期望信息会被写入stdout而不是stderr,因为我认为这并不表示命令出现了问题。以下是一系列可重现此问题的命令:
rm   -rf /tmp/repo /tmp/module
mkdir    /tmp/repo /tmp/module

cd /tmp/module

git init  > /dev/null
echo "foo" > foo;
git add foo > /dev/null
git commit . -m "+ foo" > /dev/null


cd /tmp/repo

git init > /dev/null
git submodule add /tmp/module/ sub-mod 1> /dev/null

如果我将最后一个命令中的重定向改为... 2> /dev/null,就不会打印任何内容。
1个回答

6
这不仅限于子模块,正如这里所指出的

子模块的注册将被报告到 stderr,因为这与 Git 中其余进度报告一致

在稍后的补丁中我们想要重用init_submodule函数,在update_clone中其标准输出将被传递到 shell,shell 以非常特定的方式读取标准输出中的参数。

你可以在这个最近的补丁中看到同样的情况:

将标准输出的输出路径重新定向到 stderr,因为它只是信息性的消息,不应由机器消耗

我们想在稍后的补丁中使用助手中的init_submodulesubmodule update 初始化子模块,有关该助手的标准输出将被 submodule update 的部分所消耗,这些部分仍然写在 shell 中。

因此,我们必须小心哪些消息在 stdout 上。


随着 Git 2.35(2022 年第一季度)的到来,编码指南文件已经更新,以明确在我们的系统中将哪些内容发送到标准错误。
请参见提交 e258eb4 (2021 年12月2日) ,作者是Eric Sunshine (sunshineco
(由Junio C Hamano -- gitster --合并于提交212962d,2021年12月15日)

CodingGuidelines:记录输出内容到stdout和stderr的区别

Signed-off-by: Eric Sunshine
Acked-by: Jeff King

在这个项目中,一个命令通常会将其主要输出发送到stdout,以便可以将其捕获到文件或通过管道发送,并将“多嘴”的消息(例如报告进度的消息)发送到stderr,以便它们不会干扰主要输出。
然而,这种做法并不一定是普遍适用的;另一种常见的做法是将只有错误消息发送到stderr,而将所有其他消息发送到stdout。
因此,通过记录stdout和stderr在此项目中的使用方式,帮助新手。

CodingGuidelines现在在其手册页面中包括以下内容:

程序输出

我们区分Git命令的主要输出和仅仅是多嘴的反馈输出(例如状态消息,运行记录或进度显示),以及错误消息。大致而言,Git命令的主要输出是那些可能希望将其捕获到文件或通过管道发送的输出;它的多嘴输出不应干扰这些用例。

因此,主要输出应发送到标准输出流(stdout),而多嘴输出应发送到标准错误流(stderr)。生成主要输出的命令示例包括git loggit showgit branch --list,它们在stdout流上生成输出。

并非所有Git命令都有主要输出;这通常适用于执行操作的命令。有些操作命令是静默的,而其他命令则是多嘴的。一个多嘴的操作命令示例是git clone,它具有“Cloning into''...”和“Checking connectivity...”状态消息,它会将它们发送到stderr流。

来自Git命令的错误消息应始终发送到stderr流。


1
很惊讶他们没有考虑添加一个标志以获取机器可读的输出... - aleclarson
1
@aleclarson 在 Git 中,机器可读的输出是默认的,并且会被发送到标准输出。其他任何内容都会被发送到标准错误输出。 - VonC
1
也许吧,但我更喜欢使用 git status--porcelain 标志来处理,而不是滥用 stderr。但这可能只是我的个人偏好。 - aleclarson
@aleclarson 我明白。我在 https://dev59.com/r2w05IYBdhLWcg3w3lkl#6978402 中提供了 --porcelain 选项。 - VonC
也许使用一个特殊字符来标识不应该被机器读取的输出会比滥用stderr更好。 - aleclarson

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