Создание собственных Python print
s для терминала и файла не сложно:
>>> import sys
>>> class tee(object):
... def __init__(self, fn='/tmp/foo.txt'):
... self.o = sys.stdout
... self.f = open(fn, 'w')
... def write(self, s):
... self.o.write(s)
... self.f.write(s)
...
>>> sys.stdout = tee()
>>> print('hello world!')
hello world!
>>>
$ cat /tmp/foo.txt
hello world!
Это должно работать как в Python 2, так и в Python 3.
Для аналогичного направления вывода из подкоманд не используйте
retvalue = subprocess.check_call(cmd, shell=True)
, который позволяет выводу cmd
перейти к его обычному "стандартному выводу", но лучше взять и переиздать его самостоятельно, как показано ниже:
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
so, se = p.communicate()
print(so)
retvalue = p.returncode
при условии, что вас не волнует стандартная ошибка (только стандартный вывод), а объем вывода из cmd
достаточно мал (поскольку .communicate
буферизует эти данные в памяти) - легко настроить, если либо предположение не соответствует тому, что вы точно хотите.
Редактировать : ОП теперь уточнил спецификации в длинном комментарии к этому ответу:
- Как сделать ответы на
вопросы хранятся в выходном файле
также? Например, в строке ок =
raw_input (подскажите) пользователь будет
задал вопрос, и я бы
как и к ответу в журнале.
Используйте такую функцию, как:
def echoed_input(prompt):
response = raw_input(prompt)
sys.stdout.f.write(response)
return response
вместо просто raw_input
в коде вашего приложения (конечно, это написано специально для взаимодействия с классом tee
, который я показал выше).
- Я читаю о Попене и общаюсь
и не использовал, так как он буферизует
данные в памяти. Здесь количество продукции
большой, и мне нужно заботиться о
стандартная ошибка со стандартным выходом
также. Знаете ли вы, если это
можно справиться с Попеном и
а метод связи тоже?
communicate
хорошо, если вы не получаете больше выходных данных (и стандартных ошибок), чем удобно помещается в памяти, скажем, не более нескольких гигабайт в зависимости от типа вашей машины повторное использование.
Если эта гипотеза будет соблюдена, просто перекодируйте вышеприведенное как:
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
so, se = p.communicate()
print(so)
retvalue = p.returncode
Т.е. просто перенаправьте stderr подкоманды, чтобы смешаться с ее stdout.
Если вам действительно нужно беспокоиться о гигабайтах (или что-то еще), приходящих на вас, то
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in p.stdout:
sys.stdout.write(p)
p.wait()
retvalue = p.returncode
(который получает и выдает по одной строке за раз) может быть предпочтительным (это зависит от cmd
, не ожидающего ничего от своего стандартного ввода , конечно ... потому что, если оно ожидает чего-то, оно не получит его, и проблема начинает становиться сложной; -).