如何将输出重定向到文件和标准输出
在 bash 中,调用 foo 会在标准输出上显示该命令的所有输出。
调用 foo > 输出
会将来自该命令的任何输出重定向到指定的文件(在本例中为“输出”)。
有没有办法将输出重定向到文件并使其显示在标准输出上?
In bash, calling foo
would display any output from that command on the stdout.
Calling foo > output
would redirect any output from that command to the file specified (in this case 'output').
Is there a way to redirect output to a file and have it display on stdout?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
T 恤非常适合这个,但这也可以完成这项工作
tee is perfect for this, but this will also do the job
您想要的命令名为
tee
:
例如,如果您只关心 stdout:
如果您想包含 stderr,请执行:
2>&1
重定向通道 2(stderr/标准错误)进入通道 1(stdout/标准输出),这样两者都被写入 stdout。 它还定向到tee
命令的给定输出文件。此外,如果您想附加到日志文件,请使用
tee -a
:The command you want is named
tee
:For example, if you only care about stdout:
If you want to include stderr, do:
2>&1
redirects channel 2 (stderr/standard error) into channel 1 (stdout/standard output), such that both is written as stdout. It is also directed to the given output file as of thetee
command.Furthermore, if you want to append to the log file, use
tee -a
as:2>&1
转储 stderr 和 stdout 流。tee outfile
获取它获取的流并将其写入屏幕和文件“outfile”。这可能是大多数人正在寻找的。 可能的情况是某个程序或脚本长时间工作并产生大量输出。 用户希望定期检查进度,但也希望将输出写入文件。
问题(特别是当混合 stdout 和 stderr 流时)是依赖于程序刷新的流。 例如,如果对 stdout 的所有写入都未刷新,但对 stderr 的所有写入都刷新,那么它们最终将在输出中不按时间顺序排列文件并显示在屏幕上。
如果程序每隔几分钟只输出 1 或 2 行来报告进度,那也是很糟糕的。 在这种情况下,如果程序没有刷新输出,用户甚至在几个小时内都不会在屏幕上看到任何输出,因为几个小时内都不会通过管道推送任何输出。
更新:程序
unbuffer
是expect
包的一部分,将解决缓冲问题。 这将导致 stdout 和 stderr 立即写入屏幕和文件,并在组合并重定向到tee
时保持它们同步。 例如:2>&1
dumps the stderr and stdout streams.tee outfile
takes the stream it gets and writes it to the screen and to the file "outfile".This is probably what most people are looking for. The likely situation is some program or script is working hard for a long time and producing a lot of output. The user wants to check it periodically for progress, but also wants the output written to a file.
The problem (especially when mixing stdout and stderr streams) is that there is reliance on the streams being flushed by the program. If, for example, all the writes to stdout are not flushed, but all the writes to stderr are flushed, then they'll end up out of chronological order in the output file and on the screen.
It's also bad if the program only outputs 1 or 2 lines every few minutes to report progress. In such a case, if the output was not flushed by the program, the user wouldn't even see any output on the screen for hours, because none of it would get pushed through the pipe for hours.
Update: The program
unbuffer
, part of theexpect
package, will solve the buffering problem. This will cause stdout and stderr to write to the screen and file immediately and keep them in sync when being combined and redirected totee
. E.g.:另一种对我有用的方法是,
如gnu bash手册
示例:
有关详细信息,请参阅 重定向
Another way that works for me is,
as shown in gnu bash manual
Example:
For more information, refer redirection
您主要可以使用 Zoredache 解决方案,但如果您不想覆盖输出文件,您应该使用 -a 选项编写 tee,如下所示:
You can primarily use Zoredache solution, but If you don't want to overwrite the output file you should write tee with -a option as follow :
需要补充的内容...
unbuffer 包对 fedora 和 redhat unix 版本下的某些包存在支持问题。
抛开麻烦
以下对我有用
Something to add ...
The package unbuffer has support issues with some packages under fedora and redhat unix releases.
Setting aside the troubles
Following worked for me
就我而言,我有带有输出日志的 Java 进程。 显示输出日志并将其重定向到文件(此处名为 logfile)的最简单解决方案是:
In my case I had the Java process with output logs. The simplest solution to display output logs and redirect them into the file(named logfile here) was:
使用
tail -f output
应该可以。Using
tail -f output
should work.您可以通过在脚本开头使用类似的内容来对整个脚本执行此操作:
这会将 stderr 和 stdout 输出重定向到名为
mylogfile
的文件,并 让一切顺利同时到标准输出。它使用了一些愚蠢的技巧:
exec
来设置重定向,tee
来复制输出,$'string'
特殊 bash 表示法指定的简单NUL
字符)来指定重新启动脚本(您的原始工作可能不会使用等效参数),pipefail
选项重新启动脚本时保留原始退出状态。丑陋但在某些情况下对我有用。
You can do that for your entire script by using something like that at the beginning of your script :
This redirect both stderr and stdout outputs to the file called
mylogfile
and let everything goes to stdout at the same time.It is used some stupid tricks :
exec
without command to setup redirections,tee
to duplicates outputs,NUL
character specified by the$'string'
special bash notation) to specify that the script is restarted (no equivalent parameter may be used by your original work),pipefail
option.Ugly but useful for me in certain situations.
由于这个用例将我带到这里,因此得到了额外的答案:
在您需要以其他用户身份执行此操作的情况下
请注意,回声将在您发生时发生,文件写入将以“some_user”发生如果您要以“some_user”身份运行 echo 并使用 >> 重定向输出,则将无法工作。 “some_file”,因为文件重定向会像您一样发生。
提示:tee 还支持使用 -a 标志追加,如果您需要以另一个用户身份替换文件中的行,您可以以所需用户身份执行 sed。
Bonus answer since this use-case brought me here:
In the case where you need to do this as some other user
Note that the echo will happen as you and the file write will happen as "some_user" what will NOT work is if you were to run the echo as "some_user" and redirect the output with >> "some_file" because the file redirect will happen as you.
Hint: tee also supports append with the -a flag, if you need to replace a line in a file as another user you could execute sed as the desired user.
<代码>< 命令> |& tee filename # 这将创建一个文件“filename”,其内容为命令状态,如果文件已存在,它将删除现有内容并写入命令状态。
<代码>< 命令> | 三通>> filename # 这会将状态附加到文件,但不会在 standard_output (屏幕)上打印命令状态。
我想通过在屏幕上使用“echo”来打印一些内容并将回显的数据附加到文件中
< command > |& tee filename
# this will create a file "filename" with command status as a content, If a file already exists it will remove existed content and writes the command status.< command > | tee >> filename
# this will append status to the file but it doesn't print the command status on standard_output (screen).I want to print something by using "echo" on screen and append that echoed data to a file
下面是一个不使用 tee 的方法:
解释:
>
将输出同时重定向到/dev/tty
和log_file.txt
。/dev/tty
是终端的字符设备。Here is a method without using tee:
Explain:
>
redirects the output to/dev/tty
andlog_file.txt
at the same time./dev/tty
is the char device for terminal.