我有一个适用于Linux的脚本,但与Windows上的Python 3不兼容(Python 3.5.2是经过测试的版本)。该脚本的目标是实时捕获子进程的stdout / stderr。这是一个重现错误的脚本:
import subprocess
import os
import sys
from multiprocessing import Process, Queue
try:
from Queue import Empty
except ImportError:
from queue import Empty # python 3.x
ON_POSIX = 'posix' in sys.builtin_module_names
def enqueue_output(out, q):
for line in iter(out.readline, b''):
q.put(line)
out.close()
def output_monitor_queue(out):
q = Queue()
p = Process(target=enqueue_output, args=(out, q))
p.start()
return q, p
def update_from_output_queue(q, out):
try:
line = q.get_nowait()
except Empty:
return out
out += str(line)
return out
def runit():
stdout, stderr = '', ''
proc = subprocess.Popen(['ipconfig.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# We need to use subprocesses to capture the IO, otherwise they will block one another
# i.e. a check against stderr will sit waiting on stderr before returning
# we use Queues to communicate
qout, pout = output_monitor_queue(proc.stdout)
qerr, perr = output_monitor_queue(proc.stderr)
prev_std = None
# Loop until the process is complete + both stdout/stderr have EOFd
while proc.poll() is None or pout.is_alive() or perr.is_alive():
# Check for updates from either (non-blocking)
stdout = update_from_output_queue(qout, stdout)
stderr = update_from_output_queue(qerr, stderr)
# If there are changes, update the db
if (stdout, stderr) != prev_std:
print(stdout, stderr)
prev_std = (stdout, stderr)
runit()
运行它时,会抛出以下错误:
Traceback(最近一次调用最后一次):文件 " C:\ Users \ IEUser \ Desktop \ failed.py",第62行,in runit()文件" C:\ Users \ IEUser \ Desktop \ failed.py",第44行,在runit中 qout,pout = output_monitor_queue(proc.stdout)文件" C:\ Users \ IEUser \ Desktop \ failed.py",第23行,在output_monitor_queue中 p.start()文件" C:\ Users \ IEUser \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ multiprocessing \ process.py", 第105行,开始 self._popen = self._Popen(self)File" C:\ Users \ IEUser \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ multiprocessing \ context.py", 第212行,在_Popen return _default_context.get_context()。Process._Popen(process_obj)文件 " C:\用户\ IEUser \应用程序数据\本地\程序\的Python \ Python35-32 \ lib中\多\ context.py&#34 ;, 第311行,在_Popen 返回Popen(process_obj)文件" C:\ Users \ IEUser \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ multiprocessing \ popen_spawn_win32.py", 第66行,在 init 中 reduction.dump(process_obj,to_child)文件" C:\ Users \ IEUser \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ multiprocessing \ reduction.py", 第59行,在转储中 ForkingPickler(文件,协议).dump(obj)TypeError:无法序列化' _io.BufferedReader'对象
是否有人遇到此问题并且知道有效的跨平台解决方案?