标准输入、输出和错误

LinuxBeginner
立即练习

简介

把每个 Linux 命令想象成一台机器:数据从一侧进入,机器对其进行处理。但与只有一个输出口的简单机器不同,Linux 命令有两个独立的出口:

  • 标准输出(stdout):「正常出口」。命令正常运行时,处理完成的结果会从这里输出。
  • 标准错误(stderr):「错误出口」。出现问题时,错误消息会从这里输出。

默认情况下,这两个出口的内容都会显示在屏幕上。

这种「数据流」模型是使用 shell 时最重要的概念之一。Linux 命令并不只是「打印文本」,它们通常会产生结构化的数据流。理解这些数据流后,重定向和管道就会变得合乎逻辑,而不再像魔法一样神秘。

在本实验中,你将运行命令,观察这两种不同的数据流如何工作。

标准输出(stdout)

先观察「正常出口」如何工作。

我们将使用用于列出文件的 ls。ls 正常运行时,会将文件名发送到标准输出。

运行以下命令:

ls -l

你应该会看到文件列表。

发生了什么?

由于命令成功运行,ls 程序将文件列表发送到了 stdout 数据流。终端会读取这个数据流并将内容显示出来。

关键点在于,终端只是标准输出的默认目标。标准输出并不永久绑定到屏幕上,因此稍后你可以将它保存到其他位置,或重定向到其他目标。

标准错误(stderr)

现在观察「错误出口」。标准错误(stderr)用于输出错误信息。

你可以让 ls 报错:要求它列出一个不存在的目录。

运行以下命令:

ls -l /nonexistent_directory

你将看到一条错误消息。

发生了什么?

命令执行失败了。它没有将消息发送到 stdout,而是发送到了 stderr 数据流。

默认情况下,终端会读取这两个数据流,因此会像显示普通文本一样显示错误消息。

这就是初学者经常认为成功消息和错误消息属于「同一种输出」的原因。它们在屏幕上看起来相似,但在内部是通过不同的通道传输的。

混合输出

现在观察命令同时产生两种输出时会发生什么。

我们要求 ls 执行两项操作:

  1. 列出当前目录 .(成功)。
  2. 列出 /fake(失败)。

运行以下命令:

ls -l . /fake

仔细查看输出。你应该会看到两部分内容:

  1. 针对 /fake 的错误消息。
  2. . 的成功列表。

发生了什么?

错误消息通过 stderr 管道传输,文件列表通过 stdout 管道传输。终端收集了这两种输出,并将它们显示在屏幕上。

这种区别非常重要。在下一个实验中,你将学习如何捕获 stdout,同时忽略 stderr。

这种分离并不只是理论概念。在实际自动化场景中,脚本通常需要保存正常结果,同时让错误继续显示;或者将错误捕获到日志中,而不让错误与有用数据混在一起。

总结

在本实验中,你通过「双出口机器」的类比,探索了「数据流」:

  • 标准输出:传输正常结果的通道。
  • 标准错误:传输错误消息的通道。

默认情况下,Linux 会将这两个数据流都显示在屏幕上。接下来,你将学习如何将它们分开。