考虑这个 Bash 函数:
func() {
( echo STDOUT; echo STDERR >&2 ) 1>$1 2>$2
}
然后是这个:
$ func /dev/stdout /dev/stdout | wc -l
2
$ func /dev/stdout /dev/stderr | wc -l
STDERR
1
这些都是预料之中的。
然后是这个:
$ func /dev/stderr /dev/stdout | wc -l
STDOUT
STDERR
0
我希望
STDOUT
1
这里:STDOUT
写入 stderr ( 看不到wc
),并且STDERR
写入 stdout ( 看到wc
)。
另一个:
$ func /dev/null /dev/stdout | wc -l
0
我希望STDERR
被写入标准输出,因此可以被看到wc
。
这里发生了什么事?
如何实现我的愿望?
执行重定向后
1>/dev/stderr
,stdout
相当于stderr
。然后当执行重定向时2>/dev/stdout
,/dev/stdout
表示原始 stderr,因此它将 stderr 重定向到已经去往的位置。两个 FD 都写入同一个位置。如果要交换 stdout 和 stderr,则需要在重定向之前将其中一个原始流保存在某处。
这会将 stdout 保存在 fd 3 上,将 stderr 复制到 stdout,将 fd 3(原始 stdout)复制到 stderr,然后关闭临时 fd 3。
您可以在调用函数时使用
3>&1
和来实现结果:/dev/fd/3