为什么stdin和stdout看似可以互换?

The*_*rty 7 c++ unix macos shell stdout

我知道stdin和stdout(至少在UNIX用语中)是流缓冲区,并且stdout用于从程序输出到控制台(或者然后由shell管道等),并且stdin用于标准输入一个程序..

那么为什么至少在macOS上它们可以互换使用(stdout作为stdin,反之亦然?

例子:

  1. 如果你运行cat /dev/stdin然后输入内容,它会回复它.像cat /dev/stdout同样的事情一样运行命令.

  2. 类似地,echo "Hey There" > /dev/stdoutecho "Hey There" > /dev/stdin两个输出"嘿"回终端.

  3. 它也适用于C++:

例:

#include <iostream>
#include <string>
#include <fstream>

int main(int argc, const char * argv[]) {
    std::string echoString;
    std::fstream stdoutFile;
    stdoutFile.open("/dev/stdout");
    stdoutFile << "Hey look! I'm using stdout properly!\nNow You trying using it wrongly: " << std::endl;
    stdoutFile >> echoString;
    stdoutFile << "You Typed: " << echoString << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

出现提示时,键入单个单词,然后按EOF(Ctrl + D)按预期工作.

Sam*_*hik 4

因为,通常,当从交互式终端调用程序时,在没有重定向的情况下,标准输入和标准输出都连接到同一终端设备,例如/dev/tty(实际设备名称因操作系统而异)。

终端设备是读/写设备。从终端设备读取读取终端输入。写入终端设备会在终端上生成输出。

您仍然有离散的文件描述符 0 和 1,但它们连接到同一设备。

将其视为单个双向管道,它dup同时连接到文件描述符 0 和 1。

Linux 的行为方式相同(您可以echo Foo >/dev/stdin看到输出):

$ ls -al /proc/self/fd/[01]
lrwx------. 1 mrsam mrsam 64 Nov 22 21:34 /proc/self/fd/0 -> /dev/pts/1
lrwx------. 1 mrsam mrsam 64 Nov 22 21:34 /proc/self/fd/1 -> /dev/pts/1
Run Code Online (Sandbox Code Playgroud)

因此,对于此进程,文件描述符 0 和 1 连接到/dev/pts/1同一个伪终端设备。无论您是从文件描述符 0 还是文件描述符 1 读取,您最终都会从同一个底层/dev设备读取,因此使用哪个实际文件描述符没有区别。

当然,这取决于操作系统。其他基于 POSIX 的操作系统可能会以其他方式实现其标准输入和输出,但您实际上无法写入标准输入并从标准输出读取。