Edit: так как кажется, что решения либо нет, либо я делаю что-то настолько нестандартное, что никто не знает - я пересмотрю свой вопрос, чтобы также спросить: каков наилучший способ ведения журналов, когда приложение Python делает много системных вызовов?
Мое приложение имеет два режима. В интерактивном режиме я хочу, чтобы весь вывод выводился на экран, а также в файл журнала, включая вывод любых системных вызовов. В режиме демона весь вывод идет в журнал. Режим демона прекрасно работает при использовании os.dup2()
. Я не могу найти способ «все» выводить в журнал в интерактивном режиме, не изменяя каждый системный вызов.
Другими словами, мне нужна функциональность командной строки 'tee' для любого вывода, генерируемого приложением python, , включая вывод системного вызова .
уточнить:
Чтобы перенаправить весь вывод, я делаю что-то вроде этого, и оно прекрасно работает:
# open our log file
so = se = open("%s.log" % self.name, 'w', 0)
# re-open stdout without buffering
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
# redirect stdout and stderr to the log file opened above
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
Самое приятное в этом то, что он не требует специальных вызовов для печати из остальной части кода. В коде также выполняются некоторые команды оболочки, поэтому хорошо не иметь дело с каждым их выводом в отдельности.
Просто я хочу сделать то же самое, за исключением дублирования вместо перенаправления.
Сначала подумал, я подумал, что простое изменение dup2
должно работать. Почему не так? Вот мой тест:
import os, sys
### my broken solution:
so = se = open("a.log", 'w', 0)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
os.dup2(sys.stdout.fileno(), so.fileno())
os.dup2(sys.stderr.fileno(), se.fileno())
###
print("foo bar")
os.spawnve("P_WAIT", "/bin/ls", ["/bin/ls"], {})
os.execve("/bin/ls", ["/bin/ls"], os.environ)
Файл "a.log" должен совпадать с тем, что отображалось на экране.