подпроцесс python proc.stderr.read () вводит дополнительные строки? - PullRequest
5 голосов
/ 02 ноября 2011

Я хочу запустить какую-нибудь команду и получить все, что выводится в stderr.У меня есть две версии функции, которая делает эту версию 1.

def Getstatusoutput(cmd):
    """Return (status, output) of executing cmd in a shell."""

    import sys
    mswindows = (sys.platform == "win32")

    import os
    if not mswindows:
        cmd = '{ ' + cmd + '; }'

    pipe = os.popen(cmd + ' 2>&1', 'r')
    text = pipe.read()
    sts = pipe.close()
    if sts is None: sts = 0
    if text[-1:] == '\n': text = text[:-1]
    return sts, text  

и версию 2

def Getstatusoutput2(cmd):
    proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    return_code = proc.wait()
    return return_code, proc.stdout.read(), proc.stderr.read()

Первая версия печатает вывод stderr, как я ожидаю.Вторая версия печатает одну пустую строку после каждой строки.Я подозреваю, что это связано с текстовой строкой [-1:] в версии 1 ... но я не могу сделать что-то подобное во второй версии.Кто-нибудь может объяснить, что мне нужно сделать, чтобы вторая функция генерировала тот же вывод, что и первая, без лишних строк между ними (и в самом конце)?

Обновление: вот как я печатаю вывод Вот как япечатаю

      status, output, error = Getstatusoutput2(cmd)
      s, oldOutput = Getstatusoutput(cmd)
      print "oldOutput = <<%s>>" % (oldOutput)
      print "error = <<%s>>" % (error)

Ответы [ 2 ]

2 голосов
/ 02 ноября 2011

Вы можете добавить .strip():

def Getstatusoutput2(cmd):
    proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    return_code = proc.wait()
    return return_code, proc.stdout.read().strip(), proc.stderr.read().strip()

Python string Документы :

string.strip(s[, chars])

Возвращает копию строки с начальным и завершающие символы удалены. Если chars опущен или None, пробел символы удалены. Если задано, а не None, chars должно быть строкой; символы в строке будут удалены с обоих концов строка, к которой вызывается этот метод.

string.whitespace

Строка, содержащая все символы, которые считается пробелом. На большинстве систем это включает в себя символы пробел , табуляция , перевод строки , возврат , перевод строки и вертикальная вкладка .

2 голосов
/ 02 ноября 2011

Вы можете использовать subprocess.check_output([cmd], stderr=STDOUT) для захвата всего вывода.

Для захвата stdout, stderr отдельно вы можете использовать .communicate():

stdout, stderr = Popen([cmd], stdout=PIPE, stderr=PIPE).communicate()

Чтобы получить все строки без символа новой строки в конце, вы можете вызвать stderr.splitlines().

Чтобы не печатать дополнительный символ новой строки, если он уже присутствует, добавьте ',' после переменной в операторе печати:

print line,

Или, если вы используете print() функцию:

print(line, end='')

Примечание

Ваш Getstatusoutput2() заблокируется, если cmd выдаст достаточно выходных данных, вместо этого используйте вышеуказанные решения:

>>> len(Getstatusoutput2(['python', '-c',"""print "*"*2**6"""])[1])
65
>>> len(Getstatusoutput2(['python', '-c',"""print "*"*2**16"""])[1])

Popen.wait() документация :

Подождите, пока дочерний процесс не прекратится. Установить и вернуть код возврата атрибута.

Предупреждение : Это приведет к взаимоблокировке при использовании stdout = PIPE и / или stderr = PIPE, и дочерний процесс генерирует достаточный вывод в канал, так что он блокирует ожидание буфера канала ОС для приема большего количества данных. Чтобы избежать этого, используйте connect ().

Связано Используйте связь () вместо stdin.write (), stdout.read () или stderr.read ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...