<p>正如在<a href="https://stackoverflow.com/users/1491895">@Barmar</a>的评论中提到的,Python3以<em>缓冲</em>文本模式打开stdin,因此<code>sys.stdin.read(1)</code>和<code>sys.stdin.readline()</code>都会导致预读,并且不会将<code>sys.stdin</code>流重新定位到新行的开头</p>
<p>然而,正如<a href="https://stackoverflow.com/users/124946">Denilson Sá Maia</a>在对<a href="https://stackoverflow.com/a/34123854/4716370">Setting smaller buffer size for sys.stdin?</a>的回答中指出的那样,有一种方法可以通过以二进制模式打开<code>sys.stdin</code>来禁用缓冲:</p>
<pre class="lang-python prettyprint-override"><code>unbuffered_stdin = os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
</code></pre>
<p>通过这样做,可以在每个子流程返回后,从该无缓冲io对象读取截断的输入,直到行尾:</p>
<pre class="lang-python prettyprint-override"><code># Run vegeta attack
for rate in rates:
# [...]
cmd = 'vegeta attack [...]'
subprocess.run(cmd, shell=True, encoding='utf-8')
# Read potentially truncated input until the next '\n' byte
# to reposition stdin to a location that is safe to consume.
unbuffered_stdin.readline()
</code></pre>
<p>打印读取行显示与以下输出类似的内容:</p>
<pre><code>b'a4b-b142-fabe0e96a6ca"],"Ce-Type":["perf.drill"],"Ce-Source":["load-test"]}}\n'
</code></pre>
<p>所有子流程现在都已成功执行:</p>
<pre><code>$ for r in results_*.bin; do vegeta report "$r"; done
[...]
Success [ratio] 100.00%
Status Codes [code:count] 200:5
Error Set:
[...]
Success [ratio] 100.00%
Status Codes [code:count] 200:7
Error Set:
[...]
Success [ratio] 100.00%
Status Codes [code:count] 200:8
Error Set:
[...]
</code></pre>
<hr/>
<p>另见<a href="https://docs.python.org/3/library/io.html#raw-i-o" rel="nofollow noreferrer">io - Raw I/O</a>(Python 3文档)</p>