连接STDOUT和STDIN是什么意思?

我正在读一本书,它说:

Every process has at least three communication channels available to it: “standard input” (STDIN), “standard output” (STDOUT), and “standard error” (STDERR).

Most commands accept their input from STDIN and write their output to STDOUT. They write error messages to STDERR. This convention lets you string commands together like building blocks to create composite pipelines.

The shell interprets the symbols <, >, and >> as instructions to reroute a command’s input or output to or from a file.

To connect the STDOUT of one command to the STDIN of another, use the | symbol, commonly known as a pipe.

ps -ef | grep httpd
所以基本上这是在说标准输入是一个命令,允许用户写入文件,而标准输出是一个命令,让bash shell将输出写入shell,而标准错误就像输出一样,但只有在文件系统出现错误时才会调用。然后我们来到连接STDOUT和STDIN的部分,我迷失了。
2个回答

标准输入和标准输出不是命令。

把命令想象成工厂里的机器,有一个装配线。大多数机器都设计为有一个传送带来输入数据和一个传送带来输出数据;它们分别是标准输入和标准输出。标准错误是机器侧面的开口,可以排出拒绝的东西。

+-------+     +------------------+       +------------------+     +------+
| input |     |    machine A     |       |    machine B     |     |output|
| reser ­­­|=====|<stdin     stdout>|=======|<stdin     stdout>|=====|bucket|
| ‑voir |  →  |      stderr      |   →   |      stderr      |  →  |      |
+-------+     +------------------+       +------------------+     +------+
                      ||                          ||

上面的图示显示了一个通过两台机器的传送带。数据来自左侧的输入储水池,被送到A机器,然后输出进一步传送到B机器(作为其输入),B机器的输出则放置在右侧的输出桶中。
从Unix的角度来看,这被称为pipeline。这个隐喻是管道:一根管子连接着A机器和B机器。上述管道的shell语法如下:
<input-file.txt commandA | commandB >output-file.txt

"

在shell中,< redirection 符号告诉shell在启动commandA之前将其标准输入连接到文件input-file.txt。(你可以在命令名称之前或之后放置重定向符号。)> 重定向符号告诉shell将commandB的标准输出连接到output-file.txt。中间的管道符号("|")告诉shell在启动它们之前将commandA的标准输出连接到commandB的标准输入。

命令可以有多个输入和多个输出,但这是另一天的内容another day

"

4视觉帮了很大的忙。 - JohnMerlino
很好的比喻。多年来,我已经理解了流水线概念,但是不知怎么地,没有人使用工厂/传送带的比喻,这使得它变得非常容易(而且简洁)理解。谢谢! - Owen Blacker
1很棒的比喻。如果你不介意的话,我会借用这个比喻。 - Tivie
Gilles,我在你的表达方式底部提出了一个问题:http://unix.stackexchange.com/q/96724/29146。你能否澄清一下? - strugee
@Gilles - 你可以包含一个示例来说明在命令之前或之后定义重定向的选项吗?例如,管道是否可以读取作为输入文件的input-file.txt > commandA或input-file.txt < commandA? - Motivated
@Motivated 重定向符号要放在输入/输出文件之前。整个重定向可以在命令名之前或之后。我确信这个问题已经在该网站上有了详细的解答,请尝试在https://unix.stackexchange.com/questions/tagged/io-redirection进行搜索。 - Gilles 'SO- stop being evil'
它还有助于记住<file0<file的简写,所以0<file cmd可以理解为:1. 连接file到 0/stdin,2. 执行cmd。相应地,对于>,如果没有在>运算符左边给出文件描述符,则推断为 1/stdout。因此,cmd >filecmd 1>file的简写,可以理解为:1. 连接 1/stdout 到file,2. 执行cmd - Carl

标准输入是一个命令,允许用户向文件写入内容。
不是一个命令,而是一个流。标准输入和输出就像邮箱一样。当程序启动时,它会被分配一个接收邮件的邮箱和一个发送邮件的邮箱。通常情况下,输入来自键盘并放入输入邮箱中,输出放入输出邮箱中最终显示在终端屏幕上。
标准输出是一个命令,将输出写入bash shell。
实际上,程序并不知道标准输出指向哪里。当你将A管道传递给B(如$ A | B),当A将邮件放入输出邮箱时,它最终会出现在B的输入邮箱中。B处理输入并将自己的邮件放入输出邮箱,这就是你在终端上看到的内容。
为了摆脱这个比喻,正如前面提到的,标准输入/输出是流。邮箱,或者称为文件描述符,是流的一端。通过管道连接A的标准输出和B的标准输入。