[英]How to read the first byte of a subprocess's stdout and then discard the rest in Python?
我想讀一個子進程'stdout的第一個字節,知道它已經開始運行了。 之后,我想丟棄所有進一步的輸出,這樣我就不用擔心緩沖區了。
做這個的最好方式是什么?
澄清:我希望子進程繼續與我的程序一起運行,我不想等待它終止或類似的東西。 理想情況下,有一些簡單的方法可以做到這一點,而不需要求助於threading
, fork
或多multiprocessing
。
如果我忽略輸出流或.close()
它,如果發送的數據超過其緩沖區中的數據,則會導致錯誤。
如果您使用的是Python 3.3+,則可以使用stdout
和stderr
的DEVNULL
特殊值來丟棄子DEVNULL
輸出。
from subprocess import Popen, DEVNULL
process = Popen(["mycmd", "myarg"], stdout=DEVNULL, stderr=DEVNULL)
或者,如果您使用的是Python 2.4+,則可以使用以下方法模擬:
import os
from subprocess import Popen
DEVNULL = open(os.devnull, 'wb')
process = Popen(["mycmd", "myarg"], stdout=DEVNULL, stderr=DEVNULL)
但是,這並沒有讓您有機會讀取stdout的第一個字節。
這似乎有效,但它並不像慣用語。
#!/usr/bin/env python3.1
import threading
import subprocess
def discard_stream_while_running(stream, process):
while process.poll() is None:
stream.read(1024)
def discard_subprocess_pipes(process, out=True, err=True, in_=True):
if out and process.stdout is not None and not process.stdout.closed:
t = threading.Thread(target=discard_stream_while_running, args=(process.stdout, process))
t.start()
if err and process.stderr is not None and not process.stderr.closed:
u = threading.Thread(target=discard_stream_while_running, args=(process.stderr, process))
u.start()
if in_ and process.stdin is not None and not process.stdin.closed:
process.stdin.close()
if __name__ == "__main__":
import tempfile
import textwrap
import time
with tempfile.NamedTemporaryFile("w+t", prefix="example-", suffix=".py") as f:
f.write(textwrap.dedent("""
import sys
import time
sys.stderr.write("{} byte(s) read through stdin.\\n"
.format(len(sys.stdin.read())))
# Push a couple of MB/s to stdout, messages to stderr.
while True:
sys.stdout.write("Hello Parent\\n" * 1000000)
sys.stderr.write("Subprocess Writing Data\\n")
time.sleep(0.5)
"""))
f.flush()
p = subprocess.Popen(["python3.1", f.name],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
p.stdin.write("Hello Child\n".encode())
discard_subprocess_pipes(p) # <-- Here
for s in range(16, 0, -1):
print("Main Process Running For", s, "More Seconds")
time.sleep(1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.