2015-02-16 7 views
0

Я запускаю команду через Popen и захватываю stderr и использую это, чтобы обновлять отображение в другом месте, это работает правильно, обновляя каждый раз, когда stderr выводит что-то, но я также пытаюсь сохранить вывод на файл журнала в реальном времени. Хотя это и записывает вывод в файл, он, похоже, не очень часто обновляет этот файл. Есть ли способ получить получение записи в файл каждый раз, когда есть что писать? Вот код:Python Popen stderr catch output

self.process1 = Popen(command, startupinfo=startupinfo, stderr=subprocess.PIPE) 
logFile = open(logFilePath, "a") 
while True: 
    line222 = self.process1.stderr.readline().decode('utf-8') 
    logFile.write(line222) 
+1

Я думаю 'logFile.flush()' сразу после 'logfFile.write()' будет делать работу – SomethingSomething

+0

А также есть метод 'Popen', который я сейчас не помню, который вы можете использовать как условие к циклу 'while', и это даст вам выходную строку за строкой ... Необходимо проверить документы docs – SomethingSomething

+0

logFile.flush() работает, спасибо. – speedyrazor

ответ

1
for line in iter(self.process1.stderr.readline,b""): 
    line222 = line.decode('utf-8') 
    logFile.write(line222) 
    logFile.flush() 
+0

код не работает. Если это Python 2, тогда 'logFile.write (line.decode ('utf-8'))' breaks, потому что 'logFile' записывает тип' str', а не 'unicode' (исключение из первого символа non-ascii). Если это Python 3, то 'iter (self.process1.stderr.readline," "):' никогда не останавливается, потому что '' '! = B'''. – jfs

+0

Буферизация не имеет значения, если вы передаете файл в 'stderr' (используется только' logfile.fileno() '). Кроме того, OP хочет, чтобы оба записывали stderr (* "каждый раз, когда stderr выводит что-то" *) * и *, чтобы сохранить его в файле. – jfs

+0

@ J.F.Sebastian, я предположил, что OP использовал python3 из-за 'decode ('utf-8')' Я просто забыл 'b'. Я не уверен, что понимаю смысл stderr, я не вижу ничего в коде OP. –

0

По умолчанию файлы использовать блок-буферные т.е. ничего не записывается на диск до переполнения буферов. Размер блока обычно составляет 4K или 8K байтов.

В вашем случае, это должно быть достаточно, чтобы сделать файл буферизация строк:

#!/usr/bin/env python 
from __future__ import print_function 
from subprocess import Popen, PIPE 

p = Popen(command, startupinfo=startupinfo, 
      stderr=PIPE, bufsize=1, # `1` means line-buffered (our end) 
      universal_newlines=True) # convert to text, normalize newlines 
with p.stderr, open(log_filename, "a", 1) as log_file: # `1` means line-buffered 
    for line in iter(p.stderr.readline, ''): 
     for file in [sys.stderr, log_file]: 
      print(line, end='', file=file) 
p.wait() 

Если вы на Python 3, то вам не нужно iter() здесь (для чтения впереди ошибка фиксируется там); вы можете использовать только for line in pipe:.

Я предполагаю, что вы использовали utf-8 в качестве держателя места для кодировки символов локали пользователя.

Смежные вопросы