Это следующий вопрос из здесь .
Куда я хочу пойти
Я хотел бы иметь возможность временно перенаправить стандартный вывод ввременный файл, в то время как Python все еще может печатать на стандартный вывод.Это может включать следующие шаги:
- Создать копию стандартного вывода (
new
) - Создать временный файл (
tmp
) - Перенаправить стандартный вывод в
tmp
- Скажите Python использовать
new
в качестве стандартного вывода - Перенаправить
tmp
в "настоящий" стандартный вывод - Сказать Python снова использовать "настоящий" стандартный вывод
- Прочитать и закрыть
tmp
Реализация
Я пытался реализовать вышеизложенное следующим образом:
import os
import subprocess
import sys
#A function that calls an external process to print to stdout as well as
#a python print to pythons stdout.
def Func(s, p = False):
subprocess.call('echo "{0}"'.format(s), shell = True)
if p:
print "print"
sil = list() # <-- Some list to store the content of the temp files
print "0.1" # Some testing of the
Func("0.2") # functionality
new = os.dup(1) # Create a copy of stdout (new)
tmp = os.tmpfile() # Create a temp file (tmp)
os.dup2(tmp.fileno(), 1) # Redirect stdout into tmp
sys.stdout = os.fdopen(new, 'w', 0) # Tell python to use new as stdout
Func("0.3", True) # <--- This should print "0.3" to the temp file and "print" to stdout
os.dup2(new, 1) # Redirect tmp into "real" stdout
sys.stdout = os.fdopen(1, 'w', 0) # Tell python to use "real" stdout again
# Read and close tmp
tmp.flush()
tmp.seek(0, os.SEEK_SET)
sil.append(tmp.read())
tmp.close()
Я быЯ хотел бы сделать небольшой перерыв, чтобы подвести итог.
Вывод на консоль до этого момента должен выглядеть следующим образом:
0.1
0.2
print
, в то время как sil
должен выглядеть следующим образом: ['0.3\n']
.Так что все работает как шарм до здесь.Однако, если я снова переделываю приведенный выше скрипт следующим образом:
print "1.1" # Some testing of the
Func("1.2") # functionality
new = os.dup(1) # Create a copy of stdout (new)
tmp = os.tmpfile() # Create a temp file (tmp)
os.dup2(tmp.fileno(), 1) # Redirect stdout into tmp
sys.stdout = os.fdopen(new, 'w', 0) # Tell python to use new as stdout
# This should print "0.3" to the temp file and "print" to stdout and is the crucial point!
Func("1.3", True)
os.dup2(new, 1) # Redirect tmp into "real" stdout
sys.stdout = os.fdopen(1, 'w', 0) # Tell python to use "real" stdout again
# Read and close tmp
tmp.flush()
tmp.seek(0, os.SEEK_SET)
sil.append(tmp.read())
, происходит ошибка, и вывод выглядит так:
1.1
1.2
/bin/sh: line 0: echo: write error: Bad file descriptor
print
, а sil
читает: ['0.3\n', '']
.
Другими словами: второй Func("1.3", True)
не может записать во временный файл.
Вопросы
- Прежде всего, я хотел бы знатьпочему мой скрипт не работает, как я хочу, чтобы он работал.То есть, почему в первой половине скрипта возможно только запись во временный файл?
- Я все еще немного озадачен использованием
dup
и dup2
.Хотя я думаю, что понимаю, как работает перенаправление stdout во временный файл, я полностью знаю, почему os.dup2(new, 1)
делает то, что делает.Может быть, ответ мог бы объяснить, что делают все dup
и dup2
в моем сценарии ^^