关于linux:如何将输出重定向到文件和标准输出

How to redirect output to a file and stdout

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

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

有没有方法将输出重定向到一个文件,并在stdout上显示它?


您需要的命令名为tee

1
foo | tee output.file

例如,如果您只关心stdout:

1
ls -a | tee output.file

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

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

2>&1将通道2(stderr/standard error)重定向到通道1(stdout/standard output),使两者都写为stdout。从tee命令开始,它也被定向到给定的输出文件。

此外,如果要附加到日志文件,请使用tee -a作为:

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


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

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

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

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

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

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

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


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

1
<command> |& tee  <outputFile>

如GNU BASH手册所示

例子:

1
ls |& tee files.txt

If ‘|&’ is used, command1’s standard error, in addition to its standard output, is connected to command2’s standard input through the pipe; it is shorthand for 2>&1 |. This implicit redirection of the standard error to the standard output is performed after any redirections specified by the command.

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


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

1
ls -lR / | tee -a output.file

要添加的内容…

包Unbuffer在Fedora和Redhat Unix版本下的某些包存在支持问题。

抛开烦恼

跟随者为我工作

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

Thank you ScDF & matthew your inputs saved me lot of time..


使用tail -f output应该有效。


奖金答案,因为这个用例把我带到这里:

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

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

请注意,echo将以"some_user"的身份发生,而文件写入将以"some_user"的身份发生,如果要以"some_user"的身份运行echo并使用>>"some_file"重定向输出,则不起作用,因为文件重定向将以您的身份发生。

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


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

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

我想通过在屏幕上使用"echo"来打印一些东西,并将这些回显的数据附加到一个文件中。

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

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

1
2
3
4
5
#!/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选项重新启动脚本时,请尝试保留原始退出状态。

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


T恤很适合这个,但这也可以

1
ls -lr / > output | cat output