不是答案,只是对@icza 所写内容的扩展,但太大而无法放入评论。
我也会尝试更多地解释为什么会这样
在 C 中不会发生
效果发生了。
您很可能使用过scanf(3),其同类函数不是对文件描述符(如系统调用包装器,如read(2) 和write(2))进行操作,而是对所谓的C标准库提供的“流”;这些设施被称为"stdio"。
这些流提供默认缓冲,stdin 通常默认为行缓冲。
考虑以下程序:
#include <stdio.h>
int main()
{
int rc, i;
printf("input integer: ");
rc = scanf("%d", &i);
if (rc != 1) {
perror("scan failed");
return 1;
}
return 0;
}
如果我们构建它
$ gcc -o scanf -W -Wall -Werror scanf.c
然后“按原样”运行,我们观察到程序已经消耗了那些额外的.ls 字符:
$ ./scanf
input integer: 3.ls
$
现在让我们看看当我们修改缓冲的想法以默认使用链接到我们的程序的libc 时会发生什么。我们将为此使用stdbuf:
$ stdbuf -i 0 ./scanf
input integer: 3.ls
scanf scanf.c
$
这就是@icza 的建议有效的原因:在 Go 中,构成os 包的变量用于保存打开到标准流的文件对象,因为它们的类型为*os.File,所以它们没有缓冲,而且它们是非常薄的包装器操作系统返回的文件描述符。
如果你需要缓冲,你应该在它所属的地方显式使用它(并且要小心:不要在缓冲包装器及其底层数据源/接收器上混合读取/写入 - 至少除非你绝对确定你的'正在做)。