如何使用Bash将标准输出和标准错误重定向并追加到文件中

如何使用Bash将标准输出和标准错误重定向并追加到文件中

技术背景

在Bash脚本编程中,经常需要将命令的标准输出(stdout)和标准错误(stderr)重定向并追加到文件中,以便记录程序运行的日志信息。这有助于后续的调试和分析工作。

实现步骤

经典且可移植的方法(Bash 4之前)

使用 cmd >> outfile 2>&1 ,该命令从左到右执行重定向:

  1. >> outfile :以追加模式打开 outfile ,并将标准输出重定向到该文件。
  2. 2>&1 :将标准错误重定向到“标准输出当前指向的位置”,即已以追加模式打开的文件。

Bash 4及以后的非可移植方法

使用 cmd &>> outfile ,这是一种更简洁的语法,功能与经典方法相同。

分别重定向到不同文件

可以将标准输出和标准错误分别重定向到不同的文件:

  • 覆盖模式:cmd > log.out 2> log_error.out
  • 追加模式:cmd >> log.out 2>> log_error.out

同时输出到文件和终端

使用 your_command 2>&1 | tee -a file.txt ,它会将所有日志存储在 file.txt 中,同时在终端输出。

脚本内重定向

可以在脚本内部使用 exec 命令进行重定向:

1
2
3
4
#!/bin/bash
exec 1>>logfile.txt
exec 2>&1
/bin/ls -ld /tmp /tnt

此脚本会将标准输出和标准错误追加到 logfile.txt 中。

多文件日志记录

1
2
3
4
5
6
7
#!/bin/bash
if [ -e lastlog.txt ] ;then
mv -f lastlog.txt lastlog.old
fi
exec 1> >(tee -a overall.log /dev/tty >lastlog.txt)
exec 2>&1
ls -ld /tnt /tmp

该脚本会创建或更新多个日志文件,并将输出同时显示在终端。

核心代码

经典重定向

1
cmd >> outfile 2>&1

Bash 4简洁语法

1
cmd &>> outfile

分别重定向到不同文件

1
cmd >> log.out 2>> log_error.out

同时输出到文件和终端

1
your_command 2>&1 | tee -a file.txt

脚本内重定向

1
2
3
4
#!/bin/bash
exec 1>>logfile.txt
exec 2>&1
/bin/ls -ld /tmp /tnt

最佳实践

  • 考虑可移植性:如果需要支持旧版本的Bash,建议使用经典的重定向方法。
  • 保持代码一致性:在同一个脚本中,尽量使用同一种重定向语法,避免混淆。
  • 合理使用文件描述符:了解文件描述符(0-9)的用途,合理利用它们进行重定向操作。

常见问题

子shell问题

使用 (cmd 2>&1) >> file.txt 会产生一个子shell,效率较低,且不适用于需要修改当前shell环境的命令(如 cdpushd )。可以使用 { cmd 2>&1; } >> file.txt 避免子shell的产生。

缓冲区问题

在交互式会话中,如果使用 tee 进行重定向,可能会遇到缓冲区问题。可以使用 stdbuf 命令来解决:

1
2
exec 2> >(exec stdbuf -i0 -o0 tee -a overall.err combined.log /dev/tty >lasterr.txt)
exec 1> >(exec stdbuf -i0 -o0 tee -a overall.log combined.log /dev/tty >lastlog.txt)

如何使用Bash将标准输出和标准错误重定向并追加到文件中
https://119291.xyz/posts/how-to-redirect-and-append-outputs-in-bash/
作者
ww
发布于
2025年5月22日
许可协议