обертывание cmd.exe с подпроцессом

Я пытаюсь обернуть cmd.exe под окнами следующей программой, но она не работает, она как будто чего-то ждет и ничего не отображает. Есть идеи, что здесь не так?

import subprocess

process = subprocess.Popen('cmd.exe', shell=False, stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=None)  
process.stdin.write("dir\r\n")  
output = process.stdout.readlines()  
print output

person user246456    schedule 08.01.2010    source источник


Ответы (3)


Это блокируется, потому что process.stdout.readlines() считывает весь вывод процесса (пока он не завершится). Поскольку cmd.exe все еще работает, он вечно ждет своего закрытия.

Чтобы исправить это, вы можете запустить отдельный поток для чтения вывода процесса. Это то, что вам нужно сделать в любом случае, если вы не вызываете communicate(), чтобы избежать возможной взаимоблокировки. Этот поток может неоднократно вызывать process.stdout.readline() и обрабатывать данные или отправлять их обратно в основной поток для обработки.

person interjay    schedule 08.01.2010
comment
я смог сделать то, что вы предлагаете, но знаю, как синхронизировать ввод и вывод? Как убедиться, что последняя команда выполнена, прежде чем переходить к следующей команде. - person user246456; 09.01.2010
comment
Я не думаю, что есть решение, которое будет работать на 100% для этого, поскольку не существует концепции ожидания следующей команды для подпроцессов. Я полагаю, вы можете попытаться обнаружить приглашение cmd.exe, но это довольно хак и не всегда будет работать. - person interjay; 09.01.2010

Обычно при попытке вызвать командную строку с реальной командой проще просто вызвать ее с параметром «/k», чем передавать команды через стандартный ввод. То есть просто вызовите «cmd.exe /k dir». Например,

from os import *
a = popen("cmd /k dir")
print (a.read())

Приведенный ниже код делает то же самое, но в нем отсутствует строка, которой вы могли бы манипулировать, поскольку он напрямую передает вывод:

from subprocess import *
Popen("cmd /k dir")
person Brian    schedule 08.01.2010
comment
+1, распечатка более читабельна, чем результаты, которые я получил, используя код операции. - person Anthony Forloney; 08.01.2010
comment
да, это работает, но мне нужно иметь возможность написать цикл интерпретатора вокруг оболочки cmd.exe. Вот почему я хотел перенаправить stdin ou stdout . Любая идея, как добиться этого, не разветвляя оболочку каждый раз? - person user246456; 08.01.2010

process = subprocess.Popen('cmd.exe /k ', shell=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=None)
process.stdin.write("dir\n")
o,e=process.communicate()
print o
process.stdin.close()

кстати, если ваша реальная задача состоит в том, чтобы сделать список каталогов, пожалуйста, используйте собственный модуль os Python, например, os.listdir(), или модуль glob... и т. д. Не вызывайте такие системные команды без необходимости. Это делает ваш код не переносимым.

person ghostdog74    schedule 08.01.2010
comment
да, я должен был быть более точным в своем вопросе. Как написано выше, идея состоит в том, чтобы обернуть оболочку в цикле iterp (может быть cmd.exe как что-то еще bash для инст.) - person user246456; 08.01.2010