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()
このプログラムは、指定されたバイト数の入力をスキップしてから、シェルアウトし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、私はstdinにパイプを使用して問題を回避し、一度に1つのチャンクでデータをフィードすることになりました。
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()