如何将 stdout 重定向到一个文件,并将 stdout+stderr 重定向到另一个文件?

Swa*_*wri 34 shell io io-redirection stdout stderr

我怎样才能达到

cmd >> file1 2>&1 1>>file2
Run Code Online (Sandbox Code Playgroud)

也就是说,stdoutstderr 应该重定向到一个文件吗?(file1) 而只有 stdout?(file2) 应该重定向到另一个(都在附加模式下)?

pLu*_*umo 43

问题是,当您重定向输出时,下一次重定向不再可用。您可以tee在子shell中使用管道来保留第二次重定向的输出:

( cmd | tee -a file2 ) >> file1 2>&1
Run Code Online (Sandbox Code Playgroud)

或者如果您想在终端中查看输出:

( cmd | tee -a file2 ) 2>&1 | tee -a file1
Run Code Online (Sandbox Code Playgroud)

为了避免将第一个 stderr 添加teefile1,您应该将命令的 stderr 重定向到某个文件描述符(例如 3),然后再次将其添加到 stdout:

( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1
Run Code Online (Sandbox Code Playgroud)

(感谢@fra-san)


Sté*_*las 16

zsh

cmd >& out+err.log > out.log
Run Code Online (Sandbox Code Playgroud)

在附加模式下:

cmd >>& out+err.log >> out.log
Run Code Online (Sandbox Code Playgroud)

在 中zsh,如果该mult_ios选项没有被禁用,当一个文件描述符(这里是 1)被多次重定向以进行写入时,shell 会实现一个内置函数tee来将输出复制到所有目标。