为什么python在刷新和使用-u时仍保持缓冲标准输出?

为什么python在刷新和使用-u时仍保持缓冲标准输出?,python,stdout,pipe,buffering,Python,Stdout,Pipe,Buffering,输出是正确的,但它仅在我按下Ctrl-D键时才开始打印,而以下内容立即开始打印: $ cat script.py import sys for line in sys.stdin: sys.stdout.write(line) sys.stdout.flush() $ cat script.py - | python -u script.py 这让我认为缓冲不是来自cat 我通过以下方式使其工作: $ cat script.py - | cat 正如这里所解释的:,但我不

输出是正确的,但它仅在我按下Ctrl-D键时才开始打印,而以下内容立即开始打印:

$ cat script.py
import sys

for line in sys.stdin:
    sys.stdout.write(line)
    sys.stdout.flush()

$ cat script.py - | python -u script.py
这让我认为缓冲不是来自cat

我通过以下方式使其工作:

$ cat script.py - | cat

正如这里所解释的:,但我不明白为什么前一个解决方案不能按预期工作。

如果输出到管道,cat默认情况下会阻止缓冲。因此,当您在cat命令中包含-(stdin)时,它会等待获得EOF(您的ctrl-D关闭stdin流)或8K(可能)数据,然后再输出任何内容

如果将cat命令更改为“cat script.py |”,您将看到它按预期工作

另外,如果在script.py的末尾添加8K条注释,它也会立即打印出来

编辑:

以上是错误的。:-)


事实证明,file.next()文件(由文件迭代器使用,即用于文件中的行)有一个隐藏的预读缓冲区,readline()不使用该缓冲区,它只读取一个字符,直到看到换行符或EOF。

Python手册页揭示了您问题的答案:

for line in iter(sys.stdin.readline, ""):

也就是说:文件对象迭代器的内部缓冲是罪魁祸首(它不会随-u一起消失)。

我编辑了我的问题,解释了为什么它似乎不是来自cat本身。您的更改没有任何区别。。。这是第一个进行缓冲的cat,因为输出将进入管道。在管道安装后更换水槽不会改变任何东西。您可以通过简单地执行“cat script.py-”并看到它立即输出script.py,因为它将发送到终端而不是管道。也许我的示例不清楚,但我认为它表明第一个cat没有缓冲区,因为script.py的内容在EOF发送到第一个cat之前显示。正如我所说,在script.py中添加8K条注释,您将看到它可以工作。我知道cat可能会缓冲其输出,但在这种情况下,它不会(例如
cat script.py-|cat
)。你的回答与我的问题无关。
   -u     Force stdin, stdout and stderr to be totally unbuffered.  On systems where it matters, also put stdin, stdout and stderr in binary mode.  Note that
          there  is  internal  buffering  in  xreadlines(),  readlines()  and file-object iterators ("for line in sys.stdin") which is not influenced by this
          option.  To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop.