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

发布于 2024-07-11 20:58:46 字数 152 浏览 8 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

蓝眼泪 2024-07-18 20:58:47

T 恤非常适合这个,但这也可以完成这项工作

ls -lr / > output | cat output

tee is perfect for this, but this will also do the job

ls -lr / > output | cat output
看透却不说透 2024-07-18 20:58:46

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

The command you want is named tee:

foo | tee output.file

For example, if you only care about stdout:

ls -a | tee output.file

If you want to include stderr, do:

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

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 the tee command.

Furthermore, if you want to append to the log file, use tee -a as:

program [arguments...] 2>&1 | tee -a outfile
苍暮颜 2024-07-18 20:58:46
$ program [arguments...] 2>&1 | tee outfile

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

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

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

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

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

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

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 the expect 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 to tee. E.g.:

$ unbuffer program [arguments...] 2>&1 | tee outfile
迷爱 2024-07-18 20:58:46

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

<command> |& tee  <outputFile>

gnu bash手册

示例:

ls |& tee files.txt

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

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

Another way that works for me is,

<command> |& tee  <outputFile>

as shown in gnu bash manual

Example:

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.

For more information, refer redirection

初懵 2024-07-18 20:58:46

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

ls -lR / | tee -a output.file

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 :

ls -lR / | tee -a output.file
粉红×色少女 2024-07-18 20:58:46

需要补充的内容...

unbuffer 包对 fedora 和 redhat unix 版本下的某些包存在支持问题。

抛开麻烦

以下对我有用

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

谢谢ScDF & matthew 你的输入节省了我很多时间..

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

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

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

做个少女永远怀春 2024-07-18 20:58:46

就我而言,我有带有输出日志的 Java 进程。 显示输出日志并将其重定向到文件(此处名为 logfile)的最简单解决方案是:

my_java_process_run_script.sh |& tee logfile

结果是 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:

my_java_process_run_script.sh |& tee logfile

Result was Java process running with output logs displaying and
putting them into the file with name logfile

爱你不解释 2024-07-18 20:58:46

使用 tail -f output 应该可以。

Using tail -f output should work.

怎樣才叫好 2024-07-18 20:58:46

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

#!/usr/bin/env bash

test x$1 = x

这会将 stderr 和 stdout 输出重定向到名为 mylogfile 的文件,并 让一切顺利同时到标准输出。

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

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

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

\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0

这会将 stderr 和 stdout 输出重定向到名为 mylogfile 的文件,并 让一切顺利同时到标准输出。

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

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

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

\x00' "$@" ) | tee mylogfile ; exit $? ; } # do whaetever you want

这会将 stderr 和 stdout 输出重定向到名为 mylogfile 的文件,并 让一切顺利同时到标准输出。

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

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

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

You can do that for your entire script by using something like that at the beginning of your script :

#!/usr/bin/env bash

test x$1 = x

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 :

  • use exec without command to setup redirections,
  • use tee to duplicates outputs,
  • restart the script with the wanted redirections,
  • use a special first parameter (a simple 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),
  • try to preserve the original exit status when restarting the script using the pipefail option.

Ugly but useful for me in certain situations.

\x00' && shift || { set -o pipefail ; ( exec 2>&1 ; $0

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 :

  • use exec without command to setup redirections,
  • use tee to duplicates outputs,
  • restart the script with the wanted redirections,
  • use a special first parameter (a simple 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),
  • try to preserve the original exit status when restarting the script using the pipefail option.

Ugly but useful for me in certain situations.

\x00' "$@" ) | tee mylogfile ; exit $? ; } # do whaetever you want

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 :

  • use exec without command to setup redirections,
  • use tee to duplicates outputs,
  • restart the script with the wanted redirections,
  • use a special first parameter (a simple 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),
  • try to preserve the original exit status when restarting the script using the pipefail option.

Ugly but useful for me in certain situations.

束缚m 2024-07-18 20:58:46

由于这个用例将我带到这里,因此得到了额外的答案:

在您需要以其他用户身份执行此操作的情况下

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

请注意,回声将在您发生时发生,文件写入将以“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

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

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.

如果没结果 2024-07-18 20:58:46

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

<代码>< 命令> | 三通>> filename # 这会将状态附加到文件,但不会在 standard_output (屏幕)上打印命令状态。

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

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

< 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

echo "hi there, Have to print this on screen and append to a file" 
讽刺将军 2024-07-18 20:58:46

下面是一个不使用 tee 的方法:

echo "some content" > /dev/tty > log_file.txt

解释:> 将输出同时重定向到 /dev/ttylog_file.txt/dev/tty 是终端的字符设备。

Here is a method without using tee:

echo "some content" > /dev/tty > log_file.txt

Explain: > redirects the output to /dev/tty and log_file.txt at the same time. /dev/tty is the char device for terminal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文