tri*_*eee 7 python subprocess input
如果您readline()从sys.stdin,将其余部分传递给子进程似乎不起作用。
import subprocess
import sys
header = sys.stdin.buffer.readline()
print(header)
subprocess.run(['nl'], check=True)
Run Code Online (Sandbox Code Playgroud)
(我用来sys.stdin.buffer避免任何编码问题;此句柄返回原始字节。)
它运行了,但我没有从子进程中得到任何输出;
import subprocess
import sys
header = sys.stdin.buffer.readline()
print(header)
subprocess.run(['nl'], check=True)
Run Code Online (Sandbox Code Playgroud)
如果我取出readline等,子进程将读取标准输入并产生我期望的输出。
bash$ printf '%s\n' foo bar baz | python demo1.py
b'foo\n'
Run Code Online (Sandbox Code Playgroud)
当我开始读取标准输入时,Python 是否正在缓冲它的其余部分,或者这里发生了什么?运行 with 并python -u不能消除问题(事实上,它的文档只提到它改变了stdoutand的行为stderr)。但如果我传递大量数据,我确实会得到一些数据:
bash$ printf '%s\n' foo bar baz |
> python -c 'import subprocess; subprocess.run(["nl"], check=True)'
1 foo
2 bar
3 baz
Run Code Online (Sandbox Code Playgroud)
(所以,看起来它从一开始就占用了 4096 个字节。)
有什么办法可以避免这种行为吗?我只想从一开始就读一行,然后将其余的传递给子进程。
sys.stdin.buffer.readline(-1)循环中重复调用没有帮助。
这实际上是Read line from shell pipeline, pass to exec, and keep to variable 的后续内容,但对我来说,我想重点关注这个问题中令人惊讶的方面。
blh*_*ing 11
这是因为sys.stdin是在默认缓冲模式下使用内置函数创建的open,该模式使用 size 的缓冲区io.DEFAULT_BUFFER_SIZE,在大多数系统上为4096或8192字节。
为了使父进程精确地消耗标准输入中的一行文本,您可以通过将参数传递给0or函数来在禁用缓冲区的情况下打开它:bufferingopenos.fdopen
# subp1.py
import os
import sys
import subprocess
# or with the platform-dependent device file:
# unbuffered_stdin = open('/dev/stdin', 'rb', buffering=0)
unbuffered_stdin = os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
print(unbuffered_stdin.readline())
subprocess.run(['nl'], check=True)
Run Code Online (Sandbox Code Playgroud)
以便:
printf "foo\nbar\n" | python subp1.py
Run Code Online (Sandbox Code Playgroud)
然后会输出:
b'foo\n'
1 bar
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
322 次 |
| 最近记录: |