我想将命令的 stderr 流保存到日志文件中,但我也想在屏幕上显示整个输出(stdout + stderr)。我怎样才能做到这一点?
我只找到了将 stdout + stderr 显示到控制台并将两个流也重定向到文件的解决方案:
foo | tee output.file
(https://stackoverflow.com/questions/418896/how-to-redirect-output-to-a-file-and-stdout)
但我只想将 stderr 重定向到日志文件。
答案1
在最近的 bash 中,您可以使用进程替换。
foo 2> >(tee stderr.txt)
这只是将 stderr 发送到运行 tee 的程序。
更便携
exec 3>&1
foo 2>&1 >&3 | tee stderr.txt
这使得文件描述符 3 成为当前标准输出(即屏幕)的副本,然后设置管道并运行foo 2>&1 >&3
。这会将 foo 的 stderr 发送到与当前 stdout (即管道)相同的位置,然后将 stdout 发送到 fd 3(原始输出)。该管道将 foo 的原始 stderr 提供给 tee,后者将其保存在文件中并将其发送到屏幕。
答案2
我能找到的最佳答案: 这里
(cmd 2> >(tee /dev/stderr)) > log
它通过管道传输两个(标准输出和标准错误) 二者皆是 (屏幕和文件) 并让您捕获在内联条件中使用时的错误 (如果) 或连续的内联命令。
前任:
$((curl "https://unix.stackexchange.com" 2> >(tee /dev/stderr)) >> logfile) && echo "some other commands if curl succeeds without error"
在其他方法中,例如像这样将管道连接到三通(|球座 ...),下一个命令(回声...) 无论如何执行(curl) 成功或失败,因为它考虑 (球座) 作为最后执行的命令,而不是 (卷曲)