在Bash中交换stdout与stderr时,为何复制而非移动文件描述符?
为什么不能用
cmd 3>&1- 1>&2- 2>&3-替代cmd 3>&1 1>&2 2>&3 3>&-? 先明确两种写法的本质区别:
第一种写法(标准交换stdout和stderr)
cmd 3>&1 1>&2 2>&3 3>&-是**安全交换文件描述符1(stdout)和2(stderr)**的标准操作,步骤拆解:
3>&1:把文件描述符3复制为当前stdout(1)的指向——相当于先把1的“输出目标”备份到3里1>&2:把stdout(1)的输出目标改成当前stderr(2)的目标2>&3:把stderr(2)的输出目标改成之前备份在3里的原stdout目标3>&-:关闭临时用的文件描述符3
整个过程完成后,stdout和stderr的输出目标完全交换,且没有丢失任何描述符的指向。
第二种写法的问题
cmd 3>&1- 1>&2- 2>&3-里的>&X-是移动文件描述符,不是复制:
- 执行
3>&1-时,会把1的输出目标转移给3,同时直接关闭1。这时候1已经是关闭状态了 - 接下来执行
1>&2-,会把2的输出目标转移给已经关闭的1,同时关闭2 - 最后
2>&3-试图把3的目标转移给已经关闭的2,结果就是stdout和stderr都被关闭,完全达不到交换的目的
简单说:交换两个描述符必须先复制其中一个到临时描述符,不能直接用“移动”操作——移动会直接关闭原描述符,导致后续步骤丢失目标指向。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

