Как записать вывод скрипта в файл и командную строку? - PullRequest
7 голосов
/ 26 сентября 2010

У меня есть долгосрочный скрипт Python, который я запускаю из командной строки. Скрипт записывает сообщения о прогрессе и результаты в стандартный вывод. Я хочу записать все, что скрипт записывает в стандартный вывод в файл, но также увидеть его в командной строке. В качестве альтернативы, я хочу, чтобы вывод сразу переходил в файл, поэтому я могу использовать tail для просмотра прогресса. Я пробовал это:

python MyLongRunngingScript.py | tee log.txt

Но он не производит никаких выходных данных (простой запуск сценария производит выходные данные, как и ожидалось). Кто-нибудь может предложить простое решение? Я использую Mac OS X 10.6.4.

Редактировать Я использую print для вывода в моем скрипте.

Ответы [ 3 ]

16 голосов
/ 26 сентября 2010

Вы на правильном пути, но проблема в том, что Python буферизует вывод.

К счастью, есть способ запретить вывод:

python -u MyLongRunngingScript.py | tee log.txt
2 голосов
/ 26 сентября 2010

Тот факт, что вы ничего не видите, вероятно, связан с тем, что происходит буферизация.Таким образом, вы получаете вывод только каждые 4 Ko текста или около того.

Вместо этого попробуйте что-то вроде этого:

class OutputSplitter(object):
    def __init__(self, real_output, *open_files):
        self.__stdout = real_output
        self.__fds = open_files
        self.encoding = real_output.encoding
    def write(self, string):
        self.__stdout.write(string) # don't catch exception on that one.
        self.__stdout.flush()
        for fd in self.__fds:
            try:
                fd.write(string)
                fd.flush()
            except IOError:
                pass # do what you want here. 
    def flush(self):
        pass # already flushed

Затем украсьте sys.stdout этим классом с помощью следующего кода:

stdout_saved = sys.stdout
logfile = open("log.txt","a") # check exception on that one.
sys.stdout = OutputSplitter(stdout_saved, logfile)

Таким образом, каждый вывод (включая print) сбрасывается в стандартный вывод и в указанный файл.Может потребоваться доработка, потому что я не тестировал эту реализацию.

Конечно, при печати сообщений можно ожидать (небольшое большую часть времени) снижения производительности.

1 голос
/ 26 сентября 2010

Вы можете попробовать сделать sys.stdout.flush() в вашем скрипте и снова запустить с tee.Когда stdout перенаправляется на tee, он может буферизироваться дольше, чем если бы он шел прямо к терминалу.

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