我怎样才能只从标准输入中读取一行,并将其余的传递给子进程?

问题描述 投票:0回答:0

如果你

readline()
sys.stdin
,将它的其余部分传递给子进程似乎不起作用。

import subprocess
import sys

header = sys.stdin.buffer.readline()
print(header)
subprocess.run(['nl'], check=True)

(我正在使用

sys.stdin.buffer
来避免任何编码问题;此句柄返回原始字节。)

这运行了,但我没有从子进程得到任何输出;

bash$ printf '%s\n' foo bar baz | python demo1.py
b'foo\n'

如果我取出

readline
等,子进程读取标准输入并产生我期望的输出。

bash$ printf '%s\n' foo bar baz |
> python -c 'import subprocess; subprocess.run(["nl"], check=True)'
     1  foo
     2  bar
     3  baz

当我开始阅读标准输入时,Python 是否缓冲了其余的标准输入,或者这里发生了什么?使用

python -u
运行并不能解决问题(事实上,它的文档只提到它改变了
stdout
stderr
的行为)。但是如果我传入大量数据,我确实会得到一些:

bash$ wc -l /etc/services
   13921 /etc/services

bash$ python demo1.py </etc/services  | head -n 3
     1     27/tcp     # NSW User System FE
     2  #                          Robert Thomas <[email protected]>
     3  #                28/tcp    Unassigned
 (... traceback from broken pipe elided ...)

bash$  fgrep -n 'NSW User System FE' /etc/services 
91:nsw-fe           27/udp     # NSW User System FE
92:nsw-fe           27/tcp     # NSW User System FE

bash$ sed -n '1,/NSW User System FE/p' /etc/services | wc
      91     449    4082

(所以,看起来它从一开始就吃掉了 4096 个字节。)

有什么办法可以避免这种行为吗?我只想从头开始阅读一行,然后将其余部分传递给子流程。

在循环中反复调用

sys.stdin.buffer.readline(-1)
没有帮助。

这实际上是 Read line from shell pipe, pass to exec, and keep to variable 但我想关注这个,对我来说,那个问题中令人惊讶的方面。

python input subprocess
© www.soinside.com 2019 - 2024. All rights reserved.