Используйте subprocess.communicate () для соединения stdin без ожидания процесса

Мне нужно запустить процесс и передать строку в stdin, которую я сейчас делаю следующим образом:

proc = subprocess.Popen(["MyCommandHere"], stdin=subprocess.PIPE) proc.communicate(input=bytes(my_str_input + "\n", "ascii")) 

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

Есть ли способ получить communicate() чтобы не блокировать или какой-либо другой способ передать мои данные? Я спрашиваю о неблокирующих сообщениях, а не о неблокирующих чтениях.

2 Solutions collect form web for “Используйте subprocess.communicate () для соединения stdin без ожидания процесса”

Два очевидных варианта:

  1. Используйте отдельный поток или процесс
  2. Подача stdin из временного файла

Опция 1:

 import threading def send_data_to(proc, inp): proc.communicate(inp) proc = subprocess.Popen(["MyCommandHere"], stdin=subprocess.PIPE) threading.Thread(target=send_data_to, args=(proc, bytes(my_str_input + "\n", "ascii"))).start() 

Вариант 2:

 import tempfile with tempfile.TemporaryFile() as tf: tf.write(bytes(my_str_input + "\n", "ascii")) tf.flush() tf.seek(0) # Might not be needed proc = subprocess.Popen(["MyCommandHere"], stdin=tf) 

Запись во временный файл может блокироваться, но обычно временные файлы оптимизируются ОС для минимизации записи на диск, когда это возможно; если процесс может занять некоторое время, вы можете заблокировать слишком длинные каналы напрямую, но небольшая блокировка для записи данных не имеет значения. Несмотря на то, что Python закрывает временный файл, когда с завершением блока (который обычно вызывает его удаление), процесс поддерживает дескриптор, предотвращая его очистку до завершения процесса.

Примечание. Все это предполагает, что процесс может не полностью поглощать ваш вход сразу при запуске. Если процесс в основном читает ввод сразу, то делает всю свою работу, вы можете упростить:

 proc.stdin.write(bytes(my_str_input + "\n", "ascii")) proc.stdin.close() # Ensures the process knows nothing else is coming 

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

Взгляните на документы на Popen.stdin . Это всего лишь стандартный записываемый объект (и, в большинстве случаев, стандартный дескриптор файла), так что вы можете сделать:

 proc.stdin.write(bytes(...)) 

Чтобы записать данные в stdin, не дожидаясь завершения подпроцесса.

  • Python преобразует двойные кавычки в одинарные кавычки в новую переменную
  • Быстро определить, является ли число простым в Python для чисел <1 млрд.
  • Python: отключить изображения в Selenium Google ChromeDriver
  • Можно ли отключить проверку сертификата SSL Python (PiP) с помощью переменной ENV?
  • Каково имя этого оператора «_» в Python?
  • Почему «if foo:» следует за веткой, даже если функция foo возвращает False?
  • Есть ли идиома Python для создания точечных папок в домашнем каталоге?
  • Зачем избегать циклов?
  • Python - лучший язык программирования в мире.