在bash中,调用foo将在stdout上显示该命令的任何输出。

调用foo>output会将该命令的任何输出重定向到指定的文件(在本例中为“output”)。

是否有方法将输出重定向到文件并将其显示在stdout上?


所需的命令名为tee:

foo | tee output.file

例如,如果您只关心stdout:

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

使用tail-f输出应该有效。


tee是完美的,但这也能完成任务

ls -lr / > output | cat output

$ program [arguments...] 2>&1 | tee outfile

2> &1转储stderr和stdout流。tee-outfile获取获取的流并将其写入屏幕和文件“outfile”。

这可能是大多数人都在寻找的。可能的情况是某些程序或脚本正在长时间努力工作并产生大量输出。用户希望定期检查进度,但也希望将输出写入文件。

问题(特别是当混合stdout和stderr流时)是依赖于程序刷新的流。例如,如果对stdout的所有写入都未刷新,但对stderr的所有写入均已刷新,那么它们将在输出文件和屏幕上按时间顺序结束。

如果程序每隔几分钟只输出1或2行来报告进度,这也很糟糕。在这种情况下,如果输出没有被程序刷新,那么用户甚至在数小时内都不会在屏幕上看到任何输出,因为这些输出都不会在数小时之内被推过管道。

更新:作为expect包的一部分,程序解包将解决缓冲问题。这将导致stdout和stderr立即写入屏幕和文件,并在合并并重定向到tee时保持同步。例如。:

$ unbuffer program [arguments...] 2>&1 | tee outfile

您可以主要使用Zoredache解决方案,但如果不想覆盖输出文件,则应使用-a选项编写tee,如下所示:

ls -lR / | tee -a output.file

另一种对我有效的方式是,

<command> |& tee  <outputFile>

如gnubash手册所示

例子:

ls |& tee files.txt

如果使用“|&”,则command1的标准错误除了其标准输出外,还通过管道连接到command2的标准输入;这是2>&1|的简写。将标准错误隐式重定向到标准输出是在命令指定的任何重定向之后执行的。

有关详细信息,请参阅重定向


要添加的内容。。。

在fedora和redhat unix版本下,软件包的非缓冲区对某些软件包存在支持问题。

抛开烦恼

跟踪对我有用

bash myscript.sh 2>&1 | tee output.log

谢谢ScDF和matthew,您的输入为我节省了大量时间。。


自从这个用例把我带到这里以来,我得到了额外的答案:

如果您需要作为其他用户执行此操作

echo "some output" | sudo -u some_user tee /some/path/some_file

请注意,echo将在您的时候发生,文件写入将在“some_user”的时候发生。如果您将echo作为“some_uuser”运行,并使用>>“some_file”重定向输出,则不会起作用,因为文件重定向将在您身上发生。

提示:tee还支持附加-a标志,如果您需要将文件中的一行替换为其他用户,则可以作为所需用户执行sed。


<command>|&tee filename#这将创建一个文件“filename”,其中命令状态为内容。如果文件已经存在,它将删除现有内容并写入命令状态。

<command>|tee>>filename#这将向文件附加状态,但不会在standard_output(屏幕)上打印命令状态。

我想通过在屏幕上使用“echo”来打印一些内容,并将这些echo数据附加到文件中

echo "hi there, Have to print this on screen and append to a file" 

您可以通过在脚本开头使用类似的方法对整个脚本执行此操作:

#!/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

这会将stderr和stdout输出重定向到名为mylogfile的文件,并让所有内容同时到达stdout。

它被使用了一些愚蠢的技巧:

在没有命令的情况下使用exec来设置重定向,使用tee复制输出,使用所需的重定向重新启动脚本,使用特殊的第一个参数($'string'特殊bash符号指定的简单NUL字符)来指定重新启动脚本(原始工作可能不会使用等效的参数),使用pipefail选项重新启动脚本时,请尝试保持原始退出状态。

丑陋,但在某些情况下对我有用。


在我的例子中,我有一个带有输出日志的Java进程。显示输出日志并将其重定向到文件(此处命名为logfile)的最简单解决方案是:

my_java_process_run_script.sh |& tee logfile

结果是Java进程正在运行,输出日志显示和将它们放入名为logfile的文件中