IT-Swarm.Net

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

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

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

有没有办法将输出重定向到文件它显示在stdout上?

798
SCdF

您想要的命令名为tee

foo | tee output.file

例如,如果你只关心stdout:

ls -a | tee output.file

如果要包含stderr,请执行以下操作:

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

2>&1将通道2(stderr /标准错误)重定向到通道1(标准输出/标准输出),这样两者都被写为标准输出。它也指向tee命令的给定输出文件。.

此外,如果要将append添加到日志文件中,请使用tee -a

program [arguments...] 2>&1 | tee -a outfile
1085
Zoredache

快速,可靠且价格合理的云托管

注册并在30天内获得$50奖金!
$ program [arguments...] 2>&1 | tee outfile

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

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

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

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

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

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

另一种对我有用的方法是,

<command> |& tee  <outputFile>

gnu bash手册所示

例:

ls |& tee files.txt

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

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

107
tsenapathy

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

ls -lR / | tee -a output.file
16
O.Badr

要添加的东西......

软件包unbuffer支持Fedora和redhat unix版本下的一些软件包的问题。.

抛开麻烦

以下为我工作

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

谢谢 ScDF马修 你的输入节省了我很多时间..

11
nitinr708

使用tail -f output应该工作。.

6
Chuck Phillips

从这个用例带来的奖励答案让我来到这里:

如果您需要像其他用户那样执行此操作

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

请注意,回声将发生在您和文件写入将发生为“some_user”将是 _不_ work是如果您将echo作为“some_user”运行并使用>>“some_file”重定向输出因为文件重定向会像你一样发生。.

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

3
jorfus

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

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

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

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

您可以在脚本开头使用类似的东西为整个脚本执行此操作:

#!/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输出重定向到名为mylogfileand的文件中,让所有内容都转到stdout 同时。.

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

  • 使用exec而无需命令来设置重定向,
  • 使用tee复制输出,
  • 使用所需的重定向重新启动脚本,
  • 使用特殊的第一个参数($'string'特殊bash表示法指定的简单NUL字符)来指定脚本重新启动(原始工作不能使用等效参数),
  • 尝试使用pipefail选项重新启动脚本时保留原始退出状态。.

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

0
Bruno BEAUFILS