подпроцесс python читает стандартный вывод - PullRequest
4 голосов
/ 08 сентября 2011

одна из моих функций в программе проверяет md5sum из hashfile

def check():
    print "checking integrity status.."
    md5 = subprocess.Popen(["md5sum", "-c", hashfile],shell=False, stdout=subprocess.PIPE)
    #fopen = open(basefile, "r")
    for f in md5.stdout.readlines():
        fc = f.rstrip("\n")
        sys.stdout.write("\rChecking..." + fc)
        sys.stdout.flush()

Теперь происходит то, что сначала выполняется вся команда, а затем для циклического чтения из md5 с использованием md5.stdout.readlines, так как она не является динамической, то есть я не получаю вывод при выполнении команды .... есть способ, которым я могу получить вывод, пока команда выполняется ...

исправлено с помощью ответа glglgl:

def check():
    print "checking integrity status.."
    md5 = subprocess.Popen(["md5sum", "-c", hashfile],shell=False, stdout=subprocess.PIPE)
    #fopen = open(basefile, "r")
    fc = "NULL"
    i = 0
    for f in iter(md5.stdout.readline, ''):
        k = fc
        fc = f.rstrip("\n")
        if "FAILED" in fc:
            print fc
        i = i + 1
        sys.stdout.write("\rChecking... "+ str(i)+ " " + fc + (' ' * (len(k) - len(fc))) )
        sys.stdout.flush()

Ответы [ 3 ]

5 голосов
/ 08 сентября 2011

Конечно. Есть несколько способов.

  1. Во-первых, вы можете работать с md5.stdout.read(), но там вам придется самостоятельно разделять строки.

  2. Затем вы можете работать с файловым объектом md5.stdout в качестве итератора. Но, похоже, есть проблема с буферизацией, т.е. е. вы не получите результаты сразу.

  3. И затем есть возможность повторно вызывать md5.stdout.readline(), пока не вернется ''.

Третий способ должен быть предпочтительным в этом случае; Я бы предложил сделать так:

...

for f in iter(md5.stdout.readline, ''):
    fc = f.rstrip("\n")
    sys.stdout.write("\rChecked " + fc)
    sys.stdout.flush()

Я также изменил текст вывода, так как вывод есть только в том случае, если проверка уже выполнена.

Если это не то, что вы хотите, а, действительно, каждый вывод выводится отдельно, вам следует перейти к пункту 1. Но это усложняет задачу. Я подумаю о решении с указанием того, что оно необходимо.

Там нужно учитывать следующие моменты:

  • read() блоков, поэтому нужно читать байт за байт (довольно некрасиво).
  • Возникает вопрос, что должно выводиться и когда должен быть прерывистый вывод.
1 голос
/ 15 мая 2012

Оригинальный плакат верен, что hashlib недоступен в Python 2.4, однако библиотека md5 доступна. Пример обходного пути:

try:
        # Python 2.5 and up.
        import hashlib
        md5Hash = hashlib.md5

except ImportError:
        # Python 2.4 and below.
        import md5
        md5Hash = md5.new

somedata = 'foobar'
hashstring = md5Hash (somedata).hexdigest ()
0 голосов
/ 08 сентября 2011

Какой размер файла?

Popen создает новый дочерний процесс для запуска команды.Возможно, он завершится до того, как вы запустите цикл for.

Вы можете проверить, завершил ли «подпроцесс» поиск атрибута кода возврата (в вашем коде: md5.returncode)

...