gpt4 book ai didi

python的subprocess.Popen跳过输入

转载 作者:行者123 更新时间:2023-11-28 16:45:44 25 4
gpt4 key购买 nike

我发现 subprocess.Popen() 在特定情况下会跳过输入字节。为了演示这个问题,我编写了以下(无意义的)程序:

import sys 
from subprocess import Popen

skip = int(sys.argv[1])
fin = sys.stdin
fin.read(skip)
cmd = 'wc -c'.split()
Popen(cmd, stdin=fin).wait()

这个程序跳过指定数量的输入字节,然后 shell out 到 wc 来计算剩余的字节数。

现在尝试使用 dd 生成输入的程序:

# skipping 0, everything works fine:
$ dd if=/dev/zero bs=1 count=100 2>/dev/null | python wc.py 0
100

$ # but skipping more than 0 yields an unexpected result.
$ # this should return 99:
$ dd if=/dev/zero bs=1 count=100 2>/dev/null | python wc.py 1
0

$ # I noticed it skips up to the 4k boundary.
$ # this should return 8191:
$ dd if=/dev/zero bs=1 count=8192 2>/dev/null | python wc.py 1
4096

谁能解释这种意外行为?已知问题?应该提交的错误? “你做错了”?

FWIW,我最终通过为标准输入使用管道解决了这个问题,然后一次输入一个 block 的数据:

p = Popen(cmd, stdin=PIPE)
chunk = fin.read(CHUNK_SIZE)
while chunk:
p.stdin.write(chunk)
chunk = fin.read(CHUNK_SIZE)
p.stdin.close()
p.wait()

最佳答案

sys.stdin 上的 .read() 函数在 Python 中进行缓冲。因此,当您读取一个字节时,Python 实际上会读取整个缓冲区,并期望您很快再次执行相同的操作。但是,读取缓冲区已满(在您的情况下为 4096)意味着操作系统认为输入已被读取并且不会将其传递给 wc

您可以使用 os.read() 来避免这个问题。跳过必需的输入字节数。这会直接调用操作系统,不会在您的进程中缓冲数据:

os.read(fin.fileno(), skip)

关于python的subprocess.Popen跳过输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14044625/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com