Сохранение файла журнала в консоли [дубликат]

Почему бы не использовать новый сканер для каждого чтения? Как показано ниже. При таком подходе вы не столкнетесь с вашей проблемой.

int i = new Scanner(System.in).nextInt();
233
задан Eric Leschinski 5 October 2015 в 15:17
поделиться

8 ответов

Если вы хотите выполнить перенаправление внутри скрипта Python, установите sys.stdout в файл-объект, трюк:

import sys
sys.stdout = open('file', 'w')
print 'test'

. Более распространенным методом является использование перенаправления оболочки при выполнении ( то же самое в Windows и Linux):

$ python foo.py > file
298
ответ дан marcog 28 August 2018 в 22:04
поделиться
import sys
sys.stdout = open('stdout.txt', 'w')
10
ответ дан Cat Plus Plus 28 August 2018 в 22:04
поделиться

Программы, написанные на других языках (например, C), должны выполнять специальную магию (называемую двойным форсированием), чтобы отделить от терминала (и предотвратить процессы зомби). Итак, я считаю, что лучшим решением является их эмулирование.

Плюсом повторного выполнения вашей программы является выбор перенаправления в командной строке, например. /usr/bin/python mycoolscript.py 2>&1 1>/dev/null

Подробнее см. в этом сообщении: В чем причина выполнения двойной вилки при создании демона?

125
ответ дан Community 28 August 2018 в 22:04
поделиться

Вот вариант ответа Yuda Prawira :

  • реализовать flush() и все атрибуты файла
  • записать его в качестве контекстного менеджера
  • захват stderr также

.

import contextlib, sys

@contextlib.contextmanager
def log_print(file):
    # capture all outputs to a log file while still printing it
    class Logger:
        def __init__(self, file):
            self.terminal = sys.stdout
            self.log = file

        def write(self, message):
            self.terminal.write(message)
            self.log.write(message)

        def __getattr__(self, attr):
            return getattr(self.terminal, attr)

    logger = Logger(file)

    _stdout = sys.stdout
    _stderr = sys.stderr
    sys.stdout = logger
    sys.stderr = logger
    yield logger.log
    sys.stdout = _stdout
    sys.stderr = _stderr


with log_print(open('mylogfile.log', 'w')):
    print('hello world')
    print('hello world on stderr', file=sys.stderr)

# you can capture the output to a string with:
# with log_print(io.StringIO()) as log:
#   ....
#   print('[captured output]', log.getvalue())
-1
ответ дан damio 28 August 2018 в 22:04
поделиться

Цитата из PEP 343 - «with» Statement (добавленный оператор импорта):

Временное перенаправление stdout:

import sys
from contextlib import contextmanager
@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

Используется как следует:

with open(filename, "w") as f:
    with stdout_redirected(f):
        print "Hello world"

Это, конечно, небезопасно, но ни один из них не делает этот танец вручную. В однопоточных программах (например, в скриптах) это популярный способ делать вещи.

21
ответ дан Georgy 28 August 2018 в 22:04
поделиться

Вам нужен терминальный мультиплексор, например, tmux или экран GNU

Я удивлен, что небольшой комментарий Райана Амоса к оригиналу вопрос - это единственное упоминание о решении, которое гораздо предпочтительнее для всех остальных, независимо от того, насколько умны хитрость python и сколько им было получено. В дополнение к комментарию Райана, tmux является хорошей альтернативой экрану GNU.

Но принцип тот же: если вы когда-нибудь захотите оставить работу на терминале, когда вы выходите из системы, идите в кафе для сэндвича, поп в ванную, домой (и т. д.), а затем позже, снова подключитесь к терминальному сеансу из любого места или любого компьютера, как будто вы никогда не отсутствовали, терминальные мультиплексоры - это ответ . Подумайте о них как VNC или удаленный рабочий стол для сеансов терминала. Все остальное - обходной путь. В качестве бонуса, когда приходит босс и / или партнер, и вы случайно создаете ctrl-w / cmd-w в своем оконном окне вместо окна вашего браузера с его изворотливым контентом, вы не потеряете последние 18 часов обработки !

2
ответ дан jfs 28 August 2018 в 22:04
поделиться

вы можете попробовать это намного лучше

import sys

class Logger(object):
    def __init__(self, filename="Default.log"):
        self.terminal = sys.stdout
        self.log = open(filename, "a")

    def write(self, message):
        self.terminal.write(message)
        self.log.write(message)

sys.stdout = Logger("yourlogfilename.txt")
print "Hello world !" # this is should be saved in yourlogfilename.txt
83
ответ дан Oleksiy 28 August 2018 в 22:04
поделиться

Другие ответы не охватывали случай, когда вы хотите, чтобы разветвленные процессы делили ваш новый stdout.

Для этого:

from os import open, close, dup, O_WRONLY

old = dup(1)
close(1)
open("file", O_WRONLY) # should open on 1

..... do stuff and then restore

close(1)
dup(old) # should dup to 1
close(old) # get rid of left overs
29
ответ дан Thomas 28 August 2018 в 22:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: