提问人:SCdF 提问时间:1/7/2009 最后编辑:MikeSCdF 更新时间:9/29/2023 访问量:1056411
如何将输出重定向到文件和 stdout
How to redirect output to a file and stdout
问:
在 bash 中,调用将在 stdout 上显示该命令的任何输出。foo
调用会将该命令的任何输出重定向到指定的文件(在本例中为“output”)。foo > 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
评论
-a
tee
output.file
ls -lR / | tee -a output.file
$?
tee
${PIPESTATUS[0]}
使用应该有效。tail -f output
T恤非常适合此,但这也可以完成这项工作
ls -lr / > output | cat output
评论
;
$ program [arguments...] 2>&1 | tee outfile
2>&1
转储 stderr 和 stdout 流。 获取它获取的流并将其写入屏幕和文件“outfile”。tee outfile
这可能是大多数人都在寻找的。可能的情况是某些程序或脚本长时间努力工作并产生大量输出。用户希望定期检查其进度,但也希望将输出写入文件。
问题(尤其是在混合 stdout 和 stderr 流时)是依赖于程序刷新的流。例如,如果未刷新对 stdout 的所有写入,但对 stderr 的所有写入都已刷新,则它们最终将在输出文件和屏幕上按时间顺序排列。
如果程序每隔几分钟只输出 1 或 2 行来报告进度,那也很糟糕。在这种情况下,如果程序没有刷新输出,用户甚至在几个小时内都不会在屏幕上看到任何输出,因为几个小时内都不会通过管道推送任何输出。
更新:程序是软件包的一部分,将解决缓冲问题。这将导致 stdout 和 stderr 立即写入屏幕和文件,并在合并和重定向到 时保持同步。例如:unbuffer
expect
tee
$ unbuffer program [arguments...] 2>&1 | tee outfile
评论
$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
python
-u
你可以主要使用Zoredache解决方案,但如果你不想覆盖输出文件,你应该用-a选项写tee,如下所示:
ls -lR / | tee -a output.file
另一种对我有用的方法是,
<command> |& tee <outputFile>
如 GNU Bash 手册所示
例:
ls |& tee files.txt
如果使用 '|&',则 command1 的标准误差除了其标准输出外,还通过管道连接到 command2 的标准输入;它是 2>&1 |的简写。在命令指定的任何重定向之后,将标准错误隐式重定向到标准输出。
有关详细信息,请参阅重定向
评论
$?
tee
${PIPESTATUS[0]}
要补充的东西......
软件包 unbuffer 对 fedora 和 redhat unix 发行版下的某些软件包存在支持问题。
抛开烦恼
以下对我有用
bash myscript.sh 2>&1 | tee output.log
评论
奖励答案,因为这个用例把我带到了这里:
如果您需要以其他用户的身份执行此操作
echo "some output" | sudo -u some_user tee -a /some/path/some_file
请注意,回显将在您发生时发生,文件写入将作为“some_user”发生,如果您要以“some_user”身份运行回显并使用“some_file”重定向输出>>则不起作用,因为文件重定向将以您的身份发生。
提示:tee 还支持附加 -a 标志,如果您需要将文件中的一行替换为其他用户,您可以以所需用户的身份执行 sed。
评论
< command > |& tee filename
# 这将创建一个文件“filename”,命令状态为内容,如果文件已经存在,它将删除现有内容并写入命令状态。
< command > | tee >> filename
# 这会将状态附加到文件中,但不会在standard_output(屏幕)上打印命令状态。
我想通过在屏幕上使用“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 输出重定向到调用的文件,并让所有内容同时转到 stdout。mylogfile
它使用了一些愚蠢的技巧:
- 使用 without 命令设置重定向,
exec
- 用于复制输出,
tee
- 使用所需的重定向重新启动脚本,
- 使用特殊的第一个参数(由特殊 Bash 表示法指定的简单字符)来指定脚本重新启动(您的原始作品不能使用等效参数),
NUL
$'string'
- 使用该选项重新启动脚本时,请尝试保留原始退出状态。
pipefail
丑陋但在某些情况下对我有用。
就我而言,我有带有输出日志的 Java 进程。显示输出日志并将其重定向到文件(此处名为 logfile)的最简单解决方案是:
my_java_process_run_script.sh |& tee logfile
结果是 Java 进程运行,输出日志显示和 将它们放入名为 logfile 的文件中
评论
|&
2>&1 | ...
tee -a
评论
foo > output
output
( )
(echo hello; echo world) | tee output.txt