Взаимодействовать с windows cmd в python

Я пытаюсь открыть CMD Windows и читать / писать в нем. Мне удалось открыть CMD с помощью этой команды:

import subprocess
proc = subprocess.Popen('cmd.exe')

Для записи в консоль CMD попробовал решение из этого вопрос:

proc.communicate('cd Documents')

Эта строка автоматически закрывала CMD, поэтому я не мог увидеть, работает ли она.

Как я могу читать и писать в Windows CMD?

1
0
2 372
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Более того, вы должны передать аргумент stdin в Popen, иначе по умолчанию ничего не перенаправляется.

import subprocess
proc = subprocess.Popen('cmd.exe',stdin=subprocess.PIPE)

теперь вы можете записывать строки в proc.stdin (не забудьте терминаторы строк и двоичный префикс для совместимости с python 3) и посмотреть, что произойдет

proc.stdin.write(b"cd Documents\n")

(хорошо, вы могли бы использовать для этого cwd="Documents", но это для примера)

В этом примере вывод перенаправлен на нет. Это означает, что вы увидите результат в текущей консоли. Не забудьте ввести стандартный ввод close, иначе это не сработает (возможно, из-за того, что буфер не очищается и / или канал нарушается при выходе из python). Затем дождитесь завершения процесса с wait()

Полный пример:

import subprocess
proc = subprocess.Popen('cmd.exe',stdin=subprocess.PIPE)
proc.stdin.write(b"cd ..\n")
# do some stuff in between...
proc.stdin.write(b"cd\n")
proc.stdin.close()
proc.wait()

на моем компьютере он печатает (извините за мой французский)

Microsoft Windows [version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Tous droits réservés.

L:\so>cd ..

L:\>cd
L:\

если вы хотите, чтобы процесс не прерывался, вы можете использовать еще несколько приемов: подпроцесс импорта, время

proc = subprocess.Popen('cmd.exe',stdin=subprocess.PIPE)
proc.stdin.write(b"cd ..\n")
proc.stdin.write(b"cd\n")
proc.stdin.flush()
time.sleep(1)
input("press return")
proc.stdin.write(b"cd\n")
proc.stdin.flush()
proc.stdin.close()
proc.wait()

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

Я пробовал ваш код, но у меня он не работал. Консоль все еще закрыта после строки: proc.stdin.write (b "cd Documents \ n")

Nightscape 13.09.2018 21:12

попробуйте полный пример

Jean-François Fabre 13.09.2018 21:13

Я пробовал ваш полный пример, но он все равно закрыл CMD: gyazo.com/f197465aedcb2de117af3fca1f258c35 (GIF)

Nightscape 13.09.2018 21:27

конечно закрывает CMD. Но после выполнения работы. позвольте мне отредактировать.

Jean-François Fabre 13.09.2018 21:28

Ага, понятно. Я понял, что proc.wait () - это строка, которая приводит к тому, что CMD остается открытым. Аналогично C# console.ReadKey ().

Nightscape 13.09.2018 21:29

Как я мог узнать, например, прочитать и сохранить ввод в переменную?

Nightscape 13.09.2018 21:31

вы можете использовать stdout=subprocess.PIPE, но проблема в том, что вы должны использовать вывод, иначе он заблокируется. Но использование вывода также может блокироваться, потому что процесс больше не пишет ... не так просто, или вам нужно создать 2 потока.

Jean-François Fabre 13.09.2018 21:34

CMD использует текстовый режим с строчной буферизацией, который требует окончания строк CRLF (т.е. "\r\n") для правильного определения новой строки и очистки файлового потока. Кроме того, передайте bufsize=0, чтобы предотвратить буферизацию объекта файла proc.stdin в Python на своей стороне. Затем вы можете взаимодействовать с CMD, не требуя, чтобы stdin.flush() и stdin.close() заставляли каждую сторону очищать свой буфер. Конечно, если вы запустите другие исполняемые файлы из этого сеанса CMD, они унаследуют канал stdin и, поскольку это канал, скорее всего, будут использовать буферизацию полный, что предотвращает любое разумное взаимодействие.

Eryk Sun 13.09.2018 22:29

@eryksun, что имеет смысл. Должен признать, я не слишком гордился stdin.flush().

Jean-François Fabre 13.09.2018 22:31

Другие вопросы по теме