Python зависает при неожиданном выходе CL с помощью модуля подпроцесса - PullRequest
1 голос
/ 28 мая 2011

Я пишу сценарий для получения номеров версий из программ командной строки, используя соответствующий им флаг командной строки 'version', например --version, -v и т. Д. Программа в целом использует регулярное выражение, чтобы получить только фактический номер версии из текстового вывода и затем сравнивает его с различными условиями минимальной требуемой или максимально допустимой версии, извлеченной из файла конфигурации xml и т. д.

Сценарий отлично работает до выполнения bzip2.

Для большинства программ нет проблем со следующим кодом:

args = 'cmd --version'

output = subprocess.getstatusoutput(args)

довольно резкий и сухой. Тем не мение! Если вы попробуете это, скажем, с помощью bzip2 (и до сих пор это единственная программа, с которой у меня возникла проблема), ala 'bzip2 --version' python "зависает", и вы должны нажать ctrl-C, чтобы выйти без записи. конечно.

Я пробовал различные варианты, такие как прохождение длинного маршрута, т. Е .:

import subprocess
from subprocess import PIPE, STDOUT

proc = subprocess.Popen(args, stdout=PIPE, stderr=STDOUT)
while(True):
    code = proc.poll()
    if(code is not None):
        break
    line = proc.stdout.readline() # or even read()
    etc.

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

Я думаю, что это только с bzip2, потому что по какой-то причине он все еще ожидает ввода с флагом --version.

Есть мысли?

Ответы [ 2 ]

0 голосов
/ 28 мая 2011

Мой bzip2 не ожидает ввода даже с --version, и вы можете легко это проверить, просто выполнив команду.

Этот код работает для меня на Python 2.4-3.2:

import subprocess
from subprocess import PIPE, STDOUT

import sys
proc = subprocess.Popen(sys.argv[1:], stdout=PIPE, stderr=STDOUT)
while True:
    line = proc.stdout.readline() # or even read()
    while True:
        line = proc.stdout.readline() # or even read()
        if not line:
            break
        print(line)
    code = proc.poll()
    if(code is not None):
        break

Никаких повешений. Я даже могу запустить vi foo.py с ним. Очевидно, что это не очень хорошо работает, так как у vi внезапно нет терминала для разговора, но я не зависаю. Выполнение :q! будет достаточно обычным. Поэтому, если ваш bzip2 ожидает ввода, просто введите что-то, и оно продолжится. Если это работает, то это проблема.

0 голосов
/ 28 мая 2011

код:

import subprocess
from subprocess import STDOUT,PIPE

proc = subprocess.Popen(("bunzip2","--version"),stdout=PIPE,stderr=STDOUT)
data = proc.stdout.read()
print data

теперь работает с bzip2 1.0.6 (или bunzip2 1.0.6, но это одно и то же приложение). Это действительно похоже на ошибку в bzip2 ... - версия должна распечатать версию и выйти, а не пытаться читать / писать в stdin.

...