将 stdout 和 stderr 重定向到单个文件
在本步骤中,你将学习如何将命令的所有输出——包括标准输出和标准错误——捕获到单个文件中。当你想要一份脚本或命令执行的完整记录时,包括发生的任何错误,这尤其有用。
让我们使用一个会产生 stdout
和 stderr
的命令。我们将尝试列出一个存在的文件(/etc/passwd
)和一个不存在的文件(non_existent_file
)。
ls -l /etc/passwd non_existent_file
你将在终端上看到两种类型的输出。第一行是标准错误,第二行是标准输出。
ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18 2024 /etc/passwd
如果你尝试仅使用 >
来重定向 stdout
,错误消息仍会显示在屏幕上。
ls -l /etc/passwd non_existent_file > output_only.txt
终端上的输出:
ls: cannot access 'non_existent_file': No such file or directory
而 output_only.txt
将只包含标准输出:
cat output_only.txt
-rw-r--r-- 1 root root 1916 Jul 18 2024 /etc/passwd
要将两个流重定向到一个文件,你可以使用 &>
运算符。这是一个方便的简写,它将标准输出(文件描述符 1)和标准错误(文件描述符 2)都发送到指定的文件。
让我们试试。我们将所有输出重定向到一个名为 combined.log
的文件。
ls -l /etc/passwd non_existent_file &> combined.log
这次,终端上没有打印任何内容。所有输出都已捕获到 combined.log
中。让我们查看其内容:
cat combined.log
你将看到文件同时包含标准输出和标准错误:
ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18 2024 /etc/passwd
还有一个更传统但稍微复杂一些的语法可以达到相同的结果:> file 2>&1
。让我们分解一下:
> file
: 这会将标准输出(文件描述符 1)重定向到 file
。
2>&1
: 这会将标准错误(文件描述符 2)重定向到与标准输出(文件描述符 1)相同的位置。由于 stdout
已经指向 file
,因此 stderr
也被发送到那里。
让我们尝试这种方法,将输出保存到 combined_traditional.log
。
ls -l /etc/passwd non_existent_file > combined_traditional.log 2>&1
同样,终端上没有输出显示。验证文件内容会显示相同的结果:
cat combined_traditional.log
ls: cannot access 'non_existent_file': No such file or directory
-rw-r--r-- 1 root root 1916 Jul 18 2024 /etc/passwd
虽然 &>
更简短且通常更受欢迎,但你会在旧脚本中经常看到 2>&1
,因此理解它的作用很重要。要追加两个流,你可以使用 &>>
或 >> file 2>&1
。