首页 > 解决方案 > 当管道传输到 sed 时,只处理 git 的一些输出

问题描述

我想在命令输出的每一行之前添加一个标签git checkout

www [master] % git checkout master --progress | sed -e "s/^/[tag] -- /"
Already on 'master'
[tag] -- Your branch is up to date with 'origin/master'.

如上输出内容,第一行Already on 'master'不能以 . 为前缀[tag] --。我该如何解决?

标签: bashgitshellsed

解决方案


在 unix 中,默认情况下,所有进程都被授予两个已经打开的流,它们可以通过它们发送输出——标准输出和标准错误——以及另一个它们可以接收输入的流——标准输入。您可以将这些视为在流程开始之前已经打开且可用的文件。

这个想法是程序应该将可能由其他程序处理的输出发送到标准输出,并且(与此示例更相关)任何错误或有用的诊断都应该发送到标准错误。如果一个程序被设计为过滤数据,它应该从标准输入中读取该数据。

在 shell 中,管道 ( |) 运算符可用于将其左侧命令的标准输出连接到其右侧命令的标准输入。在您的示例中,您已将 的标准输出连接git到 的标准输入sed。这就是为什么某些git输出带有前缀的原因。

git无前缀数据是通过其标准错误流发出的。

为了同时过滤git的标准错误流,您必须首先告诉您的 shell 将此流连接到标准输出流所在的任何位置,方法如下:

git checkout master --progress 2>&1

当它通过管道传输到sed

git checkout master --progress 2>&1 | sed -e "s/^/[tag] -- /"

...所有gits 输出都将带有前缀。

有关更多信息2>&1,请运行man bash并搜索REDIRECTION部分。


推荐阅读