Bash 将 stdout 发送到一个进程,将 stderr 发送到另一个进程
Bash Send stdout to one process and stderr to another process
我对进程替换和 bash 重定向有疑问。
考虑
$ zzz > >(echo fine) 2> >(echo error)
我期望输出 fine error
,因为 zzz 不是有效命令,但我只是得到 fine
。这是为什么?
这按预期工作
$ zzz 2> >(echo error)
error
如果我调换顺序
$ zzz 2> >(echo error) >(echo fine)
fine
error
这是因为 bash 将输出重定向(> >(echo fine)
部分)应用于 echo error
进程以及 zzz
命令本身。由于 echo fine
不对该输入做任何事情,“错误”文本就消失了。您可以通过将 echo fine
替换为实际显示输入内容的内容来看到这一点:
$ zzz > >(sed 's/^/processed through sed: /') 2> >(echo error)
$ processed through sed: error
请注意(至少在我尝试时),这看起来很奇怪,因为 shell 在 sed
开始输出修改后的错误消息之前打印了它的下一个提示符(“$”)。 >( )
创建的子进程实际上是后台运行的,因此 shell 不会等待它们完成。
如果您想避免这种情况(或至少解决它),您可以将 stdout 文件描述符复制到不同的 FD,然后将其他进程的输出重定向到该备用 FD。这是使用 FD #3 的示例:
$ zzz 3>&1 > >(echo fine) 2> >(echo error >&3)
fine
error
顺便说一句,如果您以其他顺序放置重定向,则重定向到 echo fine
逻辑上会在 echo error
进程启动后发生,因此 echo fine
的输出会转到终端正常。另一方面,如果你这样做,那么来自 echo fine
命令的错误将被重定向到 echo error
.
$ zzz 2> >(echo error) > >(echo fine; yyy)
error
fine
(在此示例中,xxx
和 yyy
的“未找到命令”错误都发送到 echo error
,后者将忽略它们。)
BTW^2,zsh 也实现了进程替换,但不以这种方式应用继承的重定向:
zsh% zzz > >(echo fine) 2> >(echo error)
fine
error
据我所知,流程替换没有任何标准定义,所以我认为没有办法定义哪个 shell 的实现“更正确”。
如上所说
$ > >(echo run) 2> >(echo zzz)
run
不输出zzz
但是我们可以通过
来规避这个问题
$ 2> >(echo zzz) > >(echo run)
zzz
run
我对进程替换和 bash 重定向有疑问。
考虑
$ zzz > >(echo fine) 2> >(echo error)
我期望输出 fine error
,因为 zzz 不是有效命令,但我只是得到 fine
。这是为什么?
这按预期工作
$ zzz 2> >(echo error)
error
如果我调换顺序
$ zzz 2> >(echo error) >(echo fine)
fine
error
这是因为 bash 将输出重定向(> >(echo fine)
部分)应用于 echo error
进程以及 zzz
命令本身。由于 echo fine
不对该输入做任何事情,“错误”文本就消失了。您可以通过将 echo fine
替换为实际显示输入内容的内容来看到这一点:
$ zzz > >(sed 's/^/processed through sed: /') 2> >(echo error)
$ processed through sed: error
请注意(至少在我尝试时),这看起来很奇怪,因为 shell 在 sed
开始输出修改后的错误消息之前打印了它的下一个提示符(“$”)。 >( )
创建的子进程实际上是后台运行的,因此 shell 不会等待它们完成。
如果您想避免这种情况(或至少解决它),您可以将 stdout 文件描述符复制到不同的 FD,然后将其他进程的输出重定向到该备用 FD。这是使用 FD #3 的示例:
$ zzz 3>&1 > >(echo fine) 2> >(echo error >&3)
fine
error
顺便说一句,如果您以其他顺序放置重定向,则重定向到 echo fine
逻辑上会在 echo error
进程启动后发生,因此 echo fine
的输出会转到终端正常。另一方面,如果你这样做,那么来自 echo fine
命令的错误将被重定向到 echo error
.
$ zzz 2> >(echo error) > >(echo fine; yyy)
error
fine
(在此示例中,xxx
和 yyy
的“未找到命令”错误都发送到 echo error
,后者将忽略它们。)
BTW^2,zsh 也实现了进程替换,但不以这种方式应用继承的重定向:
zsh% zzz > >(echo fine) 2> >(echo error)
fine
error
据我所知,流程替换没有任何标准定义,所以我认为没有办法定义哪个 shell 的实现“更正确”。
如上所说
$ > >(echo run) 2> >(echo zzz)
run
不输出zzz
但是我们可以通过
来规避这个问题$ 2> >(echo zzz) > >(echo run)
zzz
run