简体   繁体   English

PYTHON子进程cmd.exe在第一个命令后关闭

[英]PYTHON subprocess cmd.exe closes after first command

I am working on a python program which implements the cmd window. 我正在研究实现cmd窗口的python程序。 I am using subproccess with PIPE. 我在PIPE中使用子过程。 If for example i write "dir" (by stdout), I use communicate() in order to get the response from the cmd and it does work. 例如,如果我写了“ dir”(通过stdout),则我使用了communication()以便从cmd获取响应,并且它确实起作用。

The problem is that in a while True loop, this doesn't work more than one time, it seems like the subprocess closes itself.. Help me please 问题是,在一段时间的True循环中,此操作不止一次运行,似乎子进程本身已关闭。

import subprocess
process = subprocess.Popen('cmd.exe', shell=False, stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=None)
x=""
while x!="x":
    x = raw_input("insert a command \n")
    process.stdin.write(x+"\n")
    o,e=process.communicate()
    print o

process.stdin.close()

The main problem is that trying to read subprocess.PIPE deadlocks when the program is still running but there is nothing to read from stdout. 主要问题是,当程序仍在运行但试图从stdout读取任何内容时,尝试读取subprocess.PIPE死锁。 communicate() manually terminates the process to stop this. communicate()手动终止进程以停止它。

A solution would be to put the piece of code that reads stdout in another thread, and then access it via Queue, which allows for reliable sharing of data between threads by timing out instead of deadlocking. 一种解决方案是将读取stdout的代码段放在另一个线程中,然后通过Queue访问它,这可以通过超时而不是死锁来在线程之间可靠地共享数据。

The new thread will read standard out continuously, stopping when there is no more data. 新线程将连续读取标准,并在没有更多数据时停止读取。

Each line will be grabbed from the queue stream until a timeout is reached(no more data in Queue), then the list of lines will be displayed to the screen. 每行将从队列流中获取,直到达到超时(队列中没有更多数据)为止,然后行列表将显示在屏幕上。

This process will work for non-interactive programs 此过程适用于非交互式程序

import subprocess
import threading
import Queue

def read_stdout(stdout, queue):
    while True:
        queue.put(stdout.readline()) #This hangs when there is no IO

process = subprocess.Popen('cmd.exe', shell=False, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
q = Queue.Queue()
t = threading.Thread(target=read_stdout, args=(process.stdout, q))
t.daemon = True # t stops when the main thread stops
t.start()

while True:
    x = raw_input("insert a command \n")
    if x == "x":
        break
    process.stdin.write(x + "\n")
    o = []
    try:
        while True:
            o.append(q.get(timeout=.1))
    except Queue.Empty:
        print ''.join(o)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM