简介
把每个 Linux 命令想象成一台机器:数据从一侧进入,机器对其进行处理。但与只有一个输出口的简单机器不同,Linux 命令有两个独立的出口:
- 标准输出(stdout):「正常出口」。命令正常运行时,处理完成的结果会从这里输出。
- 标准错误(stderr):「错误出口」。出现问题时,错误消息会从这里输出。
默认情况下,这两个出口的内容都会显示在屏幕上。
这种「数据流」模型是使用 shell 时最重要的概念之一。Linux 命令并不只是「打印文本」,它们通常会产生结构化的数据流。理解这些数据流后,重定向和管道就会变得合乎逻辑,而不再像魔法一样神秘。
在本实验中,你将运行命令,观察这两种不同的数据流如何工作。
标准输出(stdout)
先观察「正常出口」如何工作。
我们将使用用于列出文件的 ls。ls 正常运行时,会将文件名发送到标准输出。
运行以下命令:
ls -l
你应该会看到文件列表。
发生了什么?
由于命令成功运行,ls 程序将文件列表发送到了 stdout 数据流。终端会读取这个数据流并将内容显示出来。
关键点在于,终端只是标准输出的默认目标。标准输出并不永久绑定到屏幕上,因此稍后你可以将它保存到其他位置,或重定向到其他目标。
标准错误(stderr)
现在观察「错误出口」。标准错误(stderr)用于输出错误信息。
你可以让 ls 报错:要求它列出一个不存在的目录。
运行以下命令:
ls -l /nonexistent_directory
你将看到一条错误消息。
发生了什么?
命令执行失败了。它没有将消息发送到 stdout,而是发送到了 stderr 数据流。
默认情况下,终端会读取这两个数据流,因此会像显示普通文本一样显示错误消息。
这就是初学者经常认为成功消息和错误消息属于「同一种输出」的原因。它们在屏幕上看起来相似,但在内部是通过不同的通道传输的。
混合输出
现在观察命令同时产生两种输出时会发生什么。
我们要求 ls 执行两项操作:
- 列出当前目录
.(成功)。 - 列出
/fake(失败)。
运行以下命令:
ls -l . /fake
仔细查看输出。你应该会看到两部分内容:
- 针对
/fake的错误消息。 .的成功列表。
发生了什么?
错误消息通过 stderr 管道传输,文件列表通过 stdout 管道传输。终端收集了这两种输出,并将它们显示在屏幕上。
这种区别非常重要。在下一个实验中,你将学习如何捕获 stdout,同时忽略 stderr。
这种分离并不只是理论概念。在实际自动化场景中,脚本通常需要保存正常结果,同时让错误继续显示;或者将错误捕获到日志中,而不让错误与有用数据混在一起。
总结
在本实验中,你通过「双出口机器」的类比,探索了「数据流」:
- 标准输出:传输正常结果的通道。
- 标准错误:传输错误消息的通道。
默认情况下,Linux 会将这两个数据流都显示在屏幕上。接下来,你将学习如何将它们分开。



