使用bash,如何将标准错误传递到另一个进程?

pax*_*blo 124 bash pipe stderr

众所周知如何将流程的标准输出管道传输到另一个流程标准输入:

proc1 | proc2
Run Code Online (Sandbox Code Playgroud)

但是如果我想将proc1的标准错误发送到proc2并将标准输出保留到当前位置呢?你会认为bash会有一个命令:

proc1 2| proc2
Run Code Online (Sandbox Code Playgroud)

但是,唉,没有.有没有办法做到这一点?

小智 154

还有流程替代.这使得进程替代文件.
您可以stderr按如下方式发送到文件:

process1 2> file
Run Code Online (Sandbox Code Playgroud)

但您可以将进程替换为该文件,如下所示:

process1 2> >(process2)
Run Code Online (Sandbox Code Playgroud)

这是一个发送stderr到屏幕并附加到日志文件的具体示例

sh myscript 2> >(tee -a errlog)
Run Code Online (Sandbox Code Playgroud)

  • 这正确回答了所述问题,应该是@paxdiablo接受的答案 (22认同)
  • 如果你想重定向 stderr 和 stdout 使用 `|&`,我从[这里](/sf/ask/1154812221/)学到了它 (3认同)
  • @Rolf 如果 `weston --help` 和 `less` 都期望有键盘交互,但只有其中之一收到它,那么你可能会处于尴尬的境地。尝试使用“grep”之类的东西进行测试。另外,您可能会发现鼠标/键盘输入无论如何都会转到第二个命令而不是韦斯顿。 (2认同)

pax*_*blo 88

你可以使用以下技巧来交换 stdoutstderr.然后你只需使用常规管道功能.

( proc1 3>&1 1>&2- 2>&3- ) | proc2
Run Code Online (Sandbox Code Playgroud)

提供stdout并且stderr在开始时指向同一个地方,这将为您提供所需.

什么是x>y位确实是改变文件句柄x,因此现在将其信息发送到文件句柄y当前点.对于我们的具体情况:

  • 3>&1创建一个新的句柄3,它将输出到当前句柄1(原始标准输出),只是为了保存它在下面的最后一个项目点.
  • 1>&2修改句柄1(stdout)以输出到当前句柄2(原始stderr).
  • 2>&3-修改句柄2(stderr)以输出到当前句柄3(原始标准输出)然后关闭句柄3(通过-最后).

它实际上是您在排序算法中看到的交换命令:

temp   = value1;
value1 = value2;
value2 = temp;
Run Code Online (Sandbox Code Playgroud)

  • 在这里使用"1>&2-"而不仅仅是"1>&2"的价值是什么?我不明白为什么我们要关闭fd`2`,如果我们要立即重新开启/重新分配它. (3认同)
  • @dubiousjim,在这种特殊情况下没有优势,我怀疑我这样做只是为了保持一致 - 关闭文件句柄 3 是释放它的好主意。 (2认同)

Pau*_*ce. 66

Bash 4有这个功能:

如果使用`|&',则command1的标准错误通过管道连接到command2的标准输入; 它是2>&1 |的简写.在命令指定的任何重定向之后执行标准错误的隐式重定向.

zsh也有这个功能.

-

对于其他/旧shell,只需明确输入

FirstCommand 2>&1 | OtherCommand

  • 从阅读文档来看,这与标准错误*和*输出相反,而不仅仅是stderr,但很高兴知道.我想是时候开始关注bash 4了. (14认同)

kcc*_*qzy 27

交换非常好,因为它解决了这个问题.如果您甚至不需要原始标准输出,您可以这样做:

proc1 2>&1 1>/dev/null | proc2
Run Code Online (Sandbox Code Playgroud)

订单至关重要; 你不会想要:

proc1 >/dev/null 2>&1 | proc1
Run Code Online (Sandbox Code Playgroud)

因为这会将所有内容重定向到/dev/null!