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

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

技术背景

在日常使用命令行时,我们经常会遇到这样的情况:一些程序或脚本运行时间长且产生大量输出,我们既希望能实时查看输出以了解进度,又希望将输出保存到文件中以便后续分析。此时,就需要将输出同时重定向到文件和标准输出(stdout)。

实现步骤

仅处理标准输出

若只关注标准输出,可以使用 tee 命令,它可以将输入复制到标准输出和指定文件。例如:

1
ls -a | tee output.file

上述命令会将 ls -a 的输出同时显示在屏幕上并保存到 output.file 中。

包含标准错误输出

如果要同时包含标准错误输出(stderr),可以使用 2>&1 将标准错误输出重定向到标准输出,再使用 tee 命令:

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

追加到日志文件

若要将输出追加到已有的日志文件,可使用 tee -a

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

核心代码

基本使用

1
foo | tee output.file

包含标准错误输出

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

追加到日志文件

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

使用 unbuffer 解决缓冲区问题

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

使用 |& 简化命令

1
<command> |& tee <outputFile>

以其他用户身份执行

1
echo "some output" | sudo -u some_user tee -a /some/path/some_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

最佳实践

  • 缓冲区问题:当程序输出不及时刷新缓冲区时,可能导致输出顺序混乱或长时间无输出显示。可以使用 unbuffer 命令(属于 expect 包)解决缓冲区问题:
1
unbuffer program [arguments...] 2>&1 | tee outfile
  • 简化命令:使用 |& 可以简化将标准错误输出和标准输出同时重定向的命令:
1
ls |& tee files.txt

常见问题

输出顺序混乱

当混合标准输出和标准错误输出流时,由于程序对输出流刷新的依赖,可能导致输出在文件和屏幕上的顺序不符合时间顺序。解决方法是使用 unbuffer 命令。

unbuffer 支持问题

unbuffer 包在某些 Fedora 和 Red Hat Unix 发行版下可能存在支持问题。可以尝试使用其他方法,如在脚本中使用 2>&1tee

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

不使用 tee 的方法

如果不想使用 tee,可以使用以下方法将输出同时显示在屏幕和保存到文件:

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

这里 /dev/tty 是终端的字符设备。


如何将输出重定向到文件和标准输出
https://119291.xyz/posts/how-to-redirect-output-to-a-file-and-stdout/
作者
ww
发布于
2025年5月28日
许可协议