2016-11-14 2 views
1

Я пытаюсь отправить cmd множество команд в соответствии с ответами, которые он мне отправил.отправка многих команд в cmd

Я получаю сообщение об ошибке времени выполнения:

ValueError: I/O operation on closed file 

Когда я бегу что-то вроде этого:

import subprocess 
process = subprocess.Popen("cmd.exe", stdout=subprocess.PIPE,stdin=subprocess.PIPE) 
answer = process.communicate(input="some command\n" + '\n')[0] 

""" 
choosing another command according to answer 
""" 

print process.communicate(input=another_command + '\n')[0] 
process.kill() 

Любая идея о том, как решить эту проблему?

Благодарим за помощь!

+0

Вы могли бы предоставить изображение большего размера? Вы отправляете свои команды после 'process.kill()'? Если нет, можете ли вы привести пример кода (с реальными командами вместо '' некоторая команда '')? Есть вероятность, что команда, которую вы пытаетесь запустить в cmd, завершает работу вашей оболочки. – woockashek

+0

Даже без 'process.kill()' и обе команды как '' ipconfig \ n "'. Первая команда работает, а вторая дает мне Runtime Error –

+0

Выполнение команды, вероятно, отправляет обратный код обратно, закрывая объект Popen. Например, если вы выполните ipconfig, тогда выполните 'process.poll()' вы, вероятно, увидите код возврата 0. – sytech

ответ

1

Не отправляйте свои команды в cmd.exe. Вызов ваши команды непосредственно нравится:

subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE,stdin=subprocess.PIPE) 

Возможно, вам не нужно будет трубы для стандартного ввода, если вы используете его таким образом.

+0

И если я хочу это сделать, используя 'sub-processing' и' communication() ', это возможно или нет? Большое спасибо за Вашу помощь! –

+0

@EyalS Ваша задача использовать подпроцессы и общаться() или решить специальную проблему? Вы можете использовать связь для ввода ввода в интерактивную команду. Но я не думаю, что вы можете использовать его для команд команд в cmd. – jhinghaus

+0

по какой-то причине мой компьютер не распознает cmd.exe как системную программу, даже если все мои пути совершенно правы, что заставило меня попробовать и обойти проблему с помощью подпроцесса, –

0

Ошибка в норме. communicate закрывает стандартный ввод подпроцесса, чтобы указать, что больше нет ожиданий ввода, чтобы подпроцесс мог очистить свой вывод. Таким образом, вы не можете подключить несколько вызовов communicate к одному подпроцессу.

Но если вы достаточно просты (не много килобайт входных данных), и если вам не нужно собирать и обрабатывать выходные данные одной команды перед отправкой следующего, вы должны иметь возможность записывать все команды в последовательности, считывая как можно больше выходных данных между двумя из них. После последней команды вы могли бы закрыть входной сигнал подпроцесса и дождаться его завершения, все еще сопоставив выход:

process = subprocess.Popen("cmd.exe", stdout=subprocess.PIPE, stdin=subprocess.PIPE) 
process.stdin.write("some command\n\n") 
partial_answer = process.stdout.read() # all or part of the answer can still be buffered subprocess side 
... 
process.stdin.write("some other command\n\n") 
... 
# after last command, time to close subprocess 
process.stdin.close() 
retcode = None 
while True: 
    end_of_answer += process.stdout.read() 
    if retcode is not None: break 
+0

Следите за тупиком, если вы не используете выделенный поток читателей. В Windows вы можете вызвать ['PeekNamedPipe'] (https://msdn.microsoft.com/en-us/library/aa365779), чтобы получить количество доступных байтов, используя дескриптор из 'msvcrt.get_osfhandle (process.stdout.fileno())'. Таким образом, вы не будете заходить в тупик, пытаясь прочитать больше данных о том, что доступно, в то время как cmd.exe заблокирован, ожидая команды на stdin. Для работы с оболочкой вы также можете настроить пользовательскую подсказку и прочитать байт за раз, пока не будет прочитано приглашение. – eryksun

+0

Кроме того, передайте 'bufsize = 0', чтобы предотвратить буферизацию' process.stdin', если вы не хотите повторно вызывать 'flush', а cmd.exe нуждается в том, чтобы строка заканчивалась на' '\ r \ n" ' , а не '' \ n \ n "'. – eryksun

Смежные вопросы