当程序启动时,系统的哪一部分设置三个标准流的缓冲?
这是 linux、glibc、或者 bash 的一部分吗? POSIX 定义了行为,还是 C 的一部分?
Posix 有一些答案:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05
在程序启动时,预定义了三个流,无需显式打开:标准输入(用于读取常规输入)、标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。打开时,标准错误流未完全缓冲;当且仅当可以确定标准输入和标准输出流不引用交互设备时,标准输入和标准输出流才被完全缓冲。
因此,如果系统可以确定流不是交互式的,那么它们可以完全缓冲(stderr 除外),但实际上,这决定了系统的哪一部分?
答案1
你的编程语言
此行为是 C 运行时库的产物,也是 C 编程语言的要求。其他编程语言历来都是构建在 C 运行时库之上,并从中获得这种行为。例如,对于 C++ 程序来说就是如此。 C 和 C++ 语言标准的章节在 Stack Overflow (qv) 上经常被引用。
最值得注意的是,用 Python 编写的程序具有相同的行为,并且经常被询问,有时会将责任归咎于编程语言运行时的行为被严重错误地定位。
改变使用默认语言语义的程序的这种行为(无需修改和重新编译程序)的工具有两种形式:依赖于语言的(有时是特定于运行时库的)工具,它们将自身插入运行时并更改缓冲,以及将标准 I/O 转换为运行时库决定为交互式设备的文件的工具。后一类中的工具与语言无关,包括 Bernstein ptybandage
。
进一步阅读
- https://unix.stackexchange.com/a/407472/5132
- https://unix.stackexchange.com/a/249801/5132
- http://git.musl-libc.org/cgit/musl/tree/src/stdio/__stdout_write.c#n8
只是缓冲问题的几个例子: