简体   繁体   中英

PYTHON subprocess cmd.exe closes after first command

I am working on a python program which implements the cmd window. I am using subproccess with 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.

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

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. communicate() manually terminates the process to stop this.

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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