如何将输出重定向到文件和标准输出


988

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

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

有没有一种方法可以将输出重定向到文件在stdout上显示?


3
如果有人刚到这里寻找捕获错误输出到文件,请查看-unix.stackexchange.com/questions/132511/…–
Murphy

2
关于术语的说明:当你执行foo > output的数据写入到标准输出和标准输出指定的文件output。也就是说,写入文件就是写入stdout。您在询问是否可以同时向stdout和终端写入。
威廉·普塞尔

2
@WilliamPursell我不确定您的澄清是否会改善:-)怎么样:OP正在询问是否可以将被调用程序的 stdout既指向文件又指向调用程序的 stdout(后者是被调用程序将要输出的stdout)如果没有做任何特殊的操作,则继承;即,如果调用程序是交互式bash会话,则为终端)。也许他们也想类似地控制被调用程序的stderr(“该命令的任何输出”都可以合理地解释为包括stderr)。
唐·哈奇

Answers:


1376

您想要的命令名为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

173
如果OP希望重定向“所有输出”,则还需要获取stderr:“ ls -lR / 2>&1 | tee output.file”
James Brady

45
@evanmcdonnal答案是正确的,可能不够具体或完全取决于您的要求。当然,在某些情况下,您可能不希望将stderr作为输出的一部分保存到文件中。当我5年前回答这个问题时,我以为OP只想要stdout,因为他在帖子主题中提到了stdout。
Zoredache 2014年

3
抱歉,我可能有些困惑。当我尝试它时,我没有任何输出,也许这一切都将交给stderr。
evanmcdonnal 2014年

38
使用-a论点on tee将内容追加到output.file,而不是覆盖它:ls -lR / | tee -a output.file
kazy

16
如果您$?之后使用它,它将返回状态代码tee,这可能不是您想要的。相反,您可以使用${PIPESTATUS[0]}
LaGoutte

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

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

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

问题(尤其是在混合stdout和stderr流时)是依赖于程序冲洗的流。如果,例如,所有的写入stdout都没有刷新,但所有写至标准错误满脸通红,那么他们将结束在输出文件,并在屏幕上按时间顺序排列了出来。

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

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

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

7
任何人都知道osx的'unbuffer'吗?
约翰·米

7
如果您不能使用unbuffer,则GNU coreutils包含一个名为stdbuff的工具,该工具可用于防止输出缓冲,例如$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
Peter

1
如果您使用的是OS X,则在大多数情况下使用unbuffer稍微容易一些,尽管如果您希望将信号传递给正在运行的命令,则并非如此。我的评论更针对Linux上的用户,在Linux上最有可能默认安装了coreutils。@Ethan,如果您对stdbuf语法感到困惑,请参阅以下答案:stackoverflow.com/a/25548995/942781
Peter

3
请注意,它python具有一个内置选项-u,可取消缓冲输出。
fabian789 '16

1
绝对的救生员,用于训练ML模型,我想在没有额外代码的情况下进行日志记录,还可以查看运行所花费的小时/天的输出,谢谢!
洛可可式

126

对我有用的另一种方法是

<command> |& tee  <outputFile>

gnu bash手册中所示

例:

ls |& tee files.txt

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

有关更多信息,请参考重定向


10
如果您$?之后使用它,它将返回状态代码tee,这可能不是您想要的。相反,您可以使用${PIPESTATUS[0]}
LaGoutte

1
此方法丢弃彩色控制台输出,有什么想法吗?
shakram02

试试:unbuffer ls -l --color = auto | tee files.txt
Luciano Andress Martini

17

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

ls -lR / | tee -a output.file

11

补充一下...

软件包解缓冲在fedora和redhat UNIX发行版中对某些软件包具有支持问题。

排除烦恼

以下对我有用

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

谢谢ScDF马修,您的输入为我节省了很多时间。



3

奖励答案,因为此用例将我带到了这里:

如果您需要以其他用户身份执行此操作

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

请注意,回声会发生在你和文件写入会发生的“some_user”会什么工作,如果你要运行回声为“some_user”,并与输出重定向>>“SOME_FILE”,因为文件重定向会发生跟你一样

提示:tee还支持带有-a标志的append,如果您需要以其他用户的身份替换文件中的一行,则可以以所需用户的身份执行sed。


2

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

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

我想通过在屏幕上使用“回声”来打印某些内容,并将回显的数据附加到文件中

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

1

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

#!/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复制输出,
  • 使用所需的重定向重新启动脚本,
  • 使用特殊的第一个参数(特殊bash表示法NUL指定的简单字符$'string')来指定脚本已重新启动(原始作品不得使用等效参数),
  • 使用该pipefail选项重新启动脚本时,请尝试保留原始退出状态。

难看,但在某些情况下对我有用。


-13

T恤非常适合此操作,但这也能胜任

ls -lr / > output | cat output

10
如果输出尚不存在,并且它没有执行您想要的操作,那将是一个错误,总的来说,这是荒谬的。也许您的意思是“;” 代替“ |” ?
罗伯特·甘布尔

6
即使您使用;,在执行慢速命令时,输出也会大大延迟。
Brad Koch
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.