我似乎无法弄清楚,这里发生了什么。我有 4 个版本的相同代码,唯一的区别是代码块/行的顺序。我最初的期望是重定向顺序没有任何区别,但它似乎并不正确。我还假设 >() 具有文件描述符机制的一些屏蔽属性,但没有...
请不要问我用它做什么,我也不需要替代解决方案,我想了解这段代码。或者我对过程替代的理解的信念将永远被打破......
元代码:
1_cmd_producing_both_stdout_and_stderr
|
+-stdout-> 2_cmd_producing_both_stdout_and_stderr
| |
| +-stdout-> A_awk_writing_stdout_to_file_producing_stderr
| |
| +-stderr-> B_awk_writing_stdout_to_file_producing_stderr
|
+-stdout-> 3_cmd_producing_both_stdout_and_stderr
|
+-stdout-> C_awk_writing_stdout_to_file_producing_stderr
|
+-stderr-> D_awk_writing_stdout_to_file_producing_stderr
版本 1: 1 2 AB 3 CD
版本 2: 1 2 BA 3 DC
版本 3: 1 3 DC 2 BA
版本 4: 1 3 CD 2 AB
笔记:
我也尝试了 2 AB 和 2 BA,它们产生一致的输出,类似于版本 1。
awk:GNU awk 4.1.1,API:1.1(GNU MPFR 3.1.2-p3,GNU MP 6.0.0)
bash:GNU bash,版本 4.3.30(1)-release (x86_64-pc-linux-gnu)
版本 1,这会产生我期望的输出:
( echo log; echo err 1>&2; ) \
1> >( ( echo -n '1.'; cat; echo '1.ERR' 1>&2 ; ) \
1> >( awk 'BEGIN { print "error 1" >"/dev/stderr" } { print $0 }' >out.out ) \
2> >( awk 'BEGIN { print "error 2" >"/dev/stderr" } { print $0 }' >out.err )
) \
2> >( ( echo -n '2.'; cat; echo '2.ERR' 1>&2 ; ) \
1> >( awk 'BEGIN { print "error 3" >"/dev/stderr" } { print $0 }' >err.out ) \
2> >( awk 'BEGIN { print "error 4" >"/dev/stderr" } { print $0 }' >err.err )
)
文件内容:
out.out 1.log
out.err 1.ERR
err.out 2.err
err.err 2.ERR
输出:
error 4
error 2
error 1
error 3
版本 2:
注意:与版本 1 相比,第 1 与第 2、第 3 与第 4 二级缩进行交换。
( echo log; echo err 1>&2; ) \
1> >( ( echo -n '1.'; cat; echo '1.ERR' 1>&2 ; ) \
2> >( awk 'BEGIN { print "error 1" >"/dev/stderr" } { print $0 }' >out.err ) \
1> >( awk 'BEGIN { print "error 2" >"/dev/stderr" } { print $0 }' >out.out )
) \
2> >( ( echo -n '2.'; cat; echo '2.ERR' 1>&2 ; ) \
2> >( awk 'BEGIN { print "error 3" >"/dev/stderr" } { print $0 }' >err.err ) \
1> >( awk 'BEGIN { print "error 4" >"/dev/stderr" } { print $0 }' >err.out )
)
文件内容:
(!) out.err error 2\n1.ERR
out.out 1.log
(!) err.err 2.ERR\nerror 4
err.out 2.err
输出:
error 3
error 1
版本 3:
注意:与版本 2 相比,交换了第一级缩进代码块。
( echo log; echo err 1>&2; ) \
2> >( ( echo -n '2.'; cat; echo '2.ERR' 1>&2 ; ) \
2> >( awk 'BEGIN { print "error 1" >"/dev/stderr" } { print $0 }' >err.err ) \
1> >( awk 'BEGIN { print "error 2" >"/dev/stderr" } { print $0 }' >err.out )
) \
1> >( ( echo -n '1.'; cat; echo '1.ERR' 1>&2 ; ) \
2> >( awk 'BEGIN { print "error 3" >"/dev/stderr" } { print $0 }' >out.err ) \
1> >( awk 'BEGIN { print "error 4" >"/dev/stderr" } { print $0 }' >out.out )
)
文件内容:
(!) err.err error 2\n2.ERR
(!) err.out 2.err\nerror 3
(!) out.err 1.ERR\nerror 4
out.out 1.log
输出:
error 1
(!)
版本 4:
注意:与版本 3 相比,第 1 与第 2、第 3 与第 4 二级缩进行交换。
( echo log; echo err 1>&2; ) \
2> >( ( echo -n '2.'; cat; echo '2.ERR' 1>&2 ; ) \
1> >( awk 'BEGIN { print "error 1" >"/dev/stderr" } { print $0 }' >err.out ) \
2> >( awk 'BEGIN { print "error 2" >"/dev/stderr" } { print $0 }' >err.err )
) \
1> >( ( echo -n '1.'; cat; echo '1.ERR' 1>&2 ; ) \
1> >( awk 'BEGIN { print "error 3" >"/dev/stderr" } { print $0 }' >out.out ) \
2> >( awk 'BEGIN { print "error 4" >"/dev/stderr" } { print $0 }' >out.err )
)
文件内容:
(!) err.out 2.err\nerror 4\nerror 3
err.err 2.ERR
out.out 1.log
out.err 1.ERR
输出:
error 2
error 1
(!)
版本 2、3、4 中发生了什么?