c++ - 为什么 stdin 和 stdout 看起来可以互换?

标签 c++ macos shell unix 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 都输出 'Hey There'到终端。

  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;
}

出现提示时,输入一个单词,然后按 EOF (Ctrl+D) 即可正常工作。

最佳答案

因为,通常情况下,当从交互式终端调用程序时,没有重定向,标准输入和标准输出都连接到同一终端设备,例如 /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

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

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

关于c++ - 为什么 stdin 和 stdout 看起来可以互换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40755048/

相关文章:

swift - 在单个 If 语句中检查 2 个 NSTextFields 中的值是否为正整数

linux - 如何计算 ps 命令输出 bash 脚本中 rss 和 vsz 之间的关系?

linux - 从文本文件数据库中替换当前字符串

linux - 从不同目录打开 Exec

c# - 以编程方式使用管理员帐户向注册表中的其他用户添加 key

c++ - C 中的 "All arguments to functions are passed by value",C++ 中引用传递的混淆

PHP 无法加载 Imagick 库 - PHP 启动 : Unable to load dynamic library

python - 为什么使用 virtualenv 时 Python 构建突然不是 Framework 构建?

c++ - 将任何类型的表达式放在 C++ 的初始化列表中在语法上是否正确?

c++ - 使用编码器/解码器逻辑门规则在 C++ 中编码/解码数据