почему python.subprocess зависает после proc.communicate ()?

Мне назвали интерактивную программу my_own_exe. Во-первых, это распечатывает alive, затем Вы вводите S\n и затем это распечатывает alive снова. Наконец Вы вводите L\n. Это делает некоторую обработку и выходы.

Однако, когда я называю его из следующего сценария Python, программа, казалось, зависла после распечатывания первого 'живого'.

Кто-либо может здесь сказать мне, почему это происходит?

//после чтения следовать взлетов (спасибо парни), я изменил код как следующее:

import subprocess
import time

base_command = "./AO_FelixStrategy_UnitTest --bats 31441 --chix 12467 --enxutp 31884 --turq 26372 --symbol SOGN --target_date " + '2009-Oct-16'
print base_command

proc2 = subprocess.Popen(base_command, shell=True , stdin=subprocess.PIPE,)

time.sleep(2);
print "aliv"
proc2.communicate('S\n')

print "alive"
time.sleep(6)

print "alive"
print proc2.communicate('L\n')
time.sleep(6)

программа теперь подходит к первому входу 'S\n', но затем остановилась, и я, второй 'L\n' отчасти проигнорирован.

Кто-либо может дать мне общее представление, почему это похоже на это?

15
задан Nakilon 16 April 2013 в 13:46
поделиться

2 ответа

Из документации для сообщения :

Взаимодействие с процессом: отправка данных на стандартный ввод. Считывать данные из stdout и stderr, пока не будет достигнут конец файла. Дождитесь завершения процесса.

Таким образом, после выполнения communication () процесс был завершен .

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

  • Никогда никогда не используйте shell = True - он, в свою очередь, вызывает оболочку, чтобы вызовите вашу программу, так что между вами и вашей программой будет другой процесс. Это имеет множество неприятных побочных эффектов. По умолчанию используется shell = False , поэтому вам следует придерживаться этого правила. Измените строку Popen на:

     p = subprocess.Popen (["./ AO_FelixStrategy_UnitTest ", 
    " --bats "," 31441 "," --chix "," 12467 ", 
    " --enxutp "," 31884 "," --turq "," 26372 ", 
    " --symbol "," SOGN "," --target_date ", '2009-Oct-16'], 
    stdin = subprocess.PIPE, 
    stdout = subprocess.PIPE) 
     
  • Используйте p.stdin.write для записи в процесс. Используйте p.stdout.read , чтобы читать из него.

  • Вызов p.stdout.read , если читать нечего, блокируется. Вызов p.stdin.write , если буфер записи заполнен, приведет к блокировке. Поэтому вам нужно убедиться, что у вас есть что читать / писать - вы делаете это в ОС unix, используя select . В окнах вы, к сожалению, должны прибегать к потокам. По крайней мере, это то, что Popen.communicate делает внутренне.
  • Если вы не написали AO_FelixStrategy_UnitTest , то у вас могут возникнуть дополнительные проблемы:
    • Это могло быть чтение откуда-то еще, а не стандартный ввод. Некоторые программы читают напрямую с терминала, другие используют для чтения какой-то API ОС. Это означает, что данные, записанные на стандартный ввод, не попадут в программу. Это часто верно для запросов пароля.
    • Помните, что вы должны учитывать буферы AO_FelixStrategy_UnitTest . По умолчанию стандартная связь C PIPE буферизуется, поэтому вы можете не видеть никаких выходных данных до тех пор, пока не закроете входную сторону (выполнив p.stdin.close () . Если только AO_FelixStrategy_UnitTest не сбрасывается) выводится периодически.

Вот пример кода, основанный на том, что вы описываете. Он может работать в зависимости от того, как был разработан AO_FelixStrategy_UnitTest :

p = subprocess.Popen(["./AO_FelixStrategy_UnitTest",
                      "--bats", "31441", "--chix", "12467",
                      "--enxutp", "31884", "--turq", "26372",
                      "--symbol", "SOGN", "--target_date", '2009-Oct-16'],
                     stdin=subprocess.PIPE, 
                     stdout=subprocess.PIPE)
output = p.communicate('S\nL\n')[0]
print output
28
ответ дан 1 December 2019 в 01:45
поделиться

communication () считывает данные из stdout и stderr до тех пор, пока не будет достигнут конец файла . - Он ждет, пока ваша программа не завершится.

4
ответ дан 1 December 2019 в 01:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: