在bash中,调用foo
将在stdout上显示该命令的任何输出。
调用foo > output
会将该命令的任何输出重定向到指定的文件(在本例中为“输出”)。
有没有一种方法可以将输出重定向到文件并在stdout上显示?
foo > output
的数据被写入到标准输出和标准输出为指定的文件output
。也就是说,写入文件就是写入stdout。您在询问是否可以同时向stdout和终端写入。
在bash中,调用foo
将在stdout上显示该命令的任何输出。
调用foo > output
会将该命令的任何输出重定向到指定的文件(在本例中为“输出”)。
有没有一种方法可以将输出重定向到文件并在stdout上显示?
foo > output
的数据被写入到标准输出和标准输出为指定的文件output
。也就是说,写入文件就是写入stdout。您在询问是否可以同时向stdout和终端写入。
Answers:
您想要的命令名为tee
:
foo | tee output.file
例如,如果您只关心标准输出:
ls -a | tee output.file
如果要包括stderr,请执行以下操作:
program [arguments...] 2>&1 | tee outfile
2>&1
将通道2(stderr /标准错误)重定向到通道1(stdout /标准输出),以便将两者都写为stdout。该tee
命令还将其定向到给定的输出文件。
此外,如果要附加到日志文件,请tee -a
用作:
program [arguments...] 2>&1 | tee -a outfile
-a
论点on tee
将内容追加到output.file
,而不是覆盖它:ls -lR / | tee -a output.file
$?
之后使用它,它将返回状态代码tee
,这可能不是您想要的。相反,您可以使用${PIPESTATUS[0]}
。
$ program [arguments...] 2>&1 | tee outfile
2>&1
转储stderr和stdout流。
tee outfile
接收获取的流并将其写入屏幕和文件“ outfile”。
这可能是大多数人想要的。可能的情况是某些程序或脚本长时间工作并且产生大量输出。用户希望定期检查它的进度,但也希望将输出写入文件。
问题(尤其是在混合stdout和stderr流时)是依赖于程序冲洗的流。如果,例如,所有的写入stdout都没有刷新,但所有写至标准错误是满脸通红,那么他们将结束在输出文件,并在屏幕上按时间顺序排列了出来。
如果程序每隔几分钟仅输出1或2行以报告进度,那也很糟糕。在这种情况下,如果程序未刷新输出,则用户甚至在数小时内都不会在屏幕上看到任何输出,因为数小时内不会有任何输出通过管道。
更新:该程序unbuffer
是expect
软件包的一部分,它将解决缓冲问题。这将导致stdout和stderr立即写入屏幕和文件,并在组合并重定向到时保持同步tee
。例如:
$ unbuffer program [arguments...] 2>&1 | tee outfile
python
具有一个内置选项-u
,可取消缓冲输出。
对我有用的另一种方法是
<command> |& tee <outputFile>
如gnu bash手册中所示
例:
ls |& tee files.txt
如果使用'|&',则command1的标准错误(除了其标准输出)还通过管道连接到command2的标准输入;它是2>&1 |的简写。将标准错误隐式重定向到标准输出是在命令指定的任何重定向之后执行的。
有关更多信息,请参考重定向
$?
之后使用它,它将返回状态代码tee
,这可能不是您想要的。相反,您可以使用${PIPESTATUS[0]}
。
您可以通过在脚本的开头使用类似的方法来对整个脚本执行此操作:
#!/usr/bin/env bash
test x$1 = x$'\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0 $'\x00' "$@" ) | tee mylogfile ; exit $? ; }
# do whaetever you want
这两种重定向标准错误和标准输出输出到文件称为mylogfile
并且让一切都到stdout 在同一时间。
它使用了一些愚蠢的技巧:
exec
不使用命令来设置重定向,tee
复制输出,NUL
指定的简单字符$'string'
)来指定脚本已重新启动(原始作品不得使用等效参数),pipefail
选项重新启动脚本时,请尝试保留原始退出状态。难看,但在某些情况下对我有用。