无法将subprocess.PIPE传递给Windows上的进程

时间:2016-07-29 17:38:35

标签: python windows python-3.x

我有一个适用于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'对象

是否有人遇到此问题并且知道有效的跨平台解决方案?

0 个答案:

没有答案