为什么 Bash 在将 stdout 重定向到 stderr 两次时输出两行(`>&2` 和 `>/dev/stderr`)?

Shu*_*eng 0 bash

为什么以下输出重定向会导致打印两行?

\n

>&2stdout 复制到 stderr 并>/dev/stderrstdout 重定向到 stderr。

\n

我期望只有一条输出线echo foo输出被重定向到 stderr。

\n

为什么我看不到两条输出行:echo foo >/dev/stderr 2>&1echo foo >/dev/stdout 2>&1两条输出行?

\n
\xe2\x9e\x9c  app git:(python3.10-pipeline) \xe2\x9c\x97 echo foo >/dev/stderr >&2\nfoo\nfoo\n\xe2\x9e\x9c  app git:(python3.10-pipeline) \xe2\x9c\x97 echo foo >/dev/stdout >&2\nfoo\nfoo\n
Run Code Online (Sandbox Code Playgroud)\n

Kus*_*nda 5

bashshell 中,两次重定向同一流将导致流的内容被重定向到最后一个(最右边)的目的地。确实,如果您向bashshell 提供所显示的命令,则每个命令只会生成一行输出(在标准错误流上)。

但是,您使用的是zshshell,而不是bash. 在zshshell 中,默认情况下,shell 会将同一流的多次重定向视为复制该流的请求,就像tee已使用过一样。

这意味着

echo hello >/dev/stderr >&2
Run Code Online (Sandbox Code Playgroud)

或者

echo hello >file1 >file2 >file3
Run Code Online (Sandbox Code Playgroud)

分别重定向标准输出两次和树次,将以与以下相同的方式复制标准输出流

echo hello | tee /dev/stderr >&2
Run Code Online (Sandbox Code Playgroud)

或者

echo hello | tee file1 file2 >file3
Run Code Online (Sandbox Code Playgroud)

会做。

您可以通过取消MULTIOSshell 中的 shell 选项 ( unsetopt MULTIOS) 来禁用此行为。