Используйте 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, не дожидаясь завершения подпроцесса.

  • Пытаясь заставить PyCharm работать, продолжайте получать «интерпретатор Python не выбран»,
  • Переключение строк в Python
  • Как импортировать папку lib внутри модулей
  • Как выполнить квадратный корень без использования математического модуля?
  • Получение ошибки 405 при попытке загрузить данные nltk
  • Пример сортировки Шварца в разделе «Обработка текста в Python»
  • Как писать необработанные байты в хранилище облачных хранилищ Google с помощью API-интерфейса GAE Python
  • Тип теста элементов python tuple / list
  • разбор формулы стиля excel
  • Python: обрезать файл до 100 строк или меньше
  • Python: ближайшая координата?
  • Python - лучший язык программирования в мире.