use*_*970 54 bash shell pipe io-redirection
我做了一个pipline
command1 | command2
Run Code Online (Sandbox Code Playgroud)
因此,command1的stdout进入command2,而command1的stderr进入终端(或shell的stdout所在的地方).
command3
当stdout仍然要命令2时,如何将command1的stderr传递给第三个进程()?
oli*_*bre 53
{ command1 2>&3 | command2; } 3>&1 1>&2 | command3
Run Code Online (Sandbox Code Playgroud)
您最多可以使用7个其他文件描述符:从3到9.
如果您想要更多解释,请询问,我可以解释;-)
{ { echo a; echo >&2 b; } 2>&3 | sed >&2 's/$/1/'; } 3>&1 1>&2 | sed 's/$/2/'
Run Code Online (Sandbox Code Playgroud)
输出:
b2
a1
Run Code Online (Sandbox Code Playgroud)
生成两个日志文件:
1.stderr
仅
2. stderr
和stdout
{ { { command 2>&1 1>&3; } | tee err-only.log; } 3>&1; } > err-and-stdout.log
Run Code Online (Sandbox Code Playgroud)
如果command
是,echo "stdout"; echo "stderr" >&2
那么我们可以这样测试:
$ { { { echo out>&3;echo err>&1;}| tee err-only.log;} 3>&1;} > err-and-stdout.log
$ head err-only.log err-and-stdout.log
==> err-only.log <==
err
==> err-and-stdout.log <==
out
err
Run Code Online (Sandbox Code Playgroud)
ant*_*tak 30
接受答案的结果的反转stdout
和stderr
.这是一个保留它们的方法(因为谷歌搜索就是为了这个目的):
{ command 2>&1 1>&3 3>&- | stderr_command; } 3>&1 1>&2 | stdout_command
Run Code Online (Sandbox Code Playgroud)
注意:
3>&-
需要防止fd 3被继承command
.(因为这会导致意想不到的结果,具体取决于command
内部的内容.)外部第一部分:
3>&1
- fd 3 for { ... }
设置为fd 1(即stdout
)1>&2
- fd 1 for { ... }
设置为fd 2(即stderr
)| stdout_command
- fd 1(was stdout
)通过管道输送stdout_command
内部部分从外部继承文件描述符:
2>&1
- fd 2 for command
设置为fd 1(即stderr
根据外部部分)1>&3
- fd 1 for command
设置为fd 3(即stdout
根据外部部分)3>&-
- fd 3 for command
设置为空(即关闭)| stderr_command
- fd 1(was stderr
)通过管道输送stderr_command
foo() {
echo a
echo b >&2
echo c
echo d >&2
}
{ foo 2>&1 1>&3 3>&- | sed -u 's/^/err: /'; } 3>&1 1>&2 | sed -u 's/^/out: /'
Run Code Online (Sandbox Code Playgroud)
out: a
err: b
err: d
out: c
Run Code Online (Sandbox Code Playgroud)
(顺序a -> c
和b -> d
将永远是不确定的,因为stderr_command
和之间没有任何形式的同步stdout_command
.)
oli*_*bre 14
{ command1 | command2; } 2>&1 | command3
Run Code Online (Sandbox Code Playgroud)
注意: commnd3
还会读取command2
标准输出(如果有的话).
为避免这种情况,您可以丢弃commnd2
标准输出:
{ command1 | command2 >/dev/null; } 2>&1 | command3
Run Code Online (Sandbox Code Playgroud)
但是,要保持command2
stdout(例如在终端),
那么请参考我的其他答案更复杂.
{ { echo -e "a\nb\nc" >&2; echo "----"; } | sed 's/$/1/'; } 2>&1 | sed 's/$/2/'
Run Code Online (Sandbox Code Playgroud)
输出:
a2
b2
c2
----12
Run Code Online (Sandbox Code Playgroud)
使用流程替换:
command1 > >(command2) 2> >(command3)
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅http://tldp.org/LDP/abs/html/process-sub.html.