[英]Pythonic way to flush() both sys.stdout & sys.stderr
[英]Python: capturing both of sys.stdout and sys.stderr as a log file
粗略地說,我想將此移植到純Python:
#!/bin/bash
{
python test.py
} &> /tmp/test.log
由於某些未知原因,此方法不起作用:
import os.path, sys
import tempfile
with open(os.path.join(tempfile.gettempdir(), "test.log"), "a") as fp:
sys.stdout = sys.stderr = fp
raise Exception("I'm dying")
當我在CentOS x86_64上使用Python 2.6.6,Python 2.7.8和Python 3.4.2對其進行測試時,生成的test.log
為空(並且我在控制台上看不到任何內容)。
但理想情況下,我想要Python 2.6的解決方案。
(目前,只要任何數據都不會簡單地消失在黑洞中,就可以容忍日志文件與stdout
和stderr
或多線程的混合輸出雜亂無章。)
請向我展示一個簡潔且可移植的解決方案,該解決方案可以在sys.stderr
上的異常堆棧跟蹤中使用。 (最好是os.dup2
以外的os.dup2
)
您可以使用如下方法:
import traceback
import sys
from contextlib import contextmanager
@contextmanager
def output_to_file(filepath, write_mode='w'):
stdout_orig = None
stderr_orig = None
stdout_orig = sys.stdout
stderr_orig = sys.stderr
f = open(filepath, write_mode)
sys.stdout = f
sys.stderr = f
try:
yield
except:
info = sys.exc_info()
f.write('\n'.join(traceback.format_exception(*info)))
f.close()
sys.stdout = stdout_orig
sys.stderr = stderr_orig
用法是:
with output_to_file('test.log'):
print('hello')
raise Exception('I am dying')
cat test.log
產生:
hello
Traceback (most recent call last):
File "<ipython-input-3-a3b702c7b741>", line 20, in outputi_to_file
yield
File "<ipython-input-4-f879d82580b2>", line 3, in <module>
raise Exception('I am dying')
Exception: I am dying
請記住,文件對象在with
塊之后關閉:)
簡單地使用這個:
sys.stdout = sys.stderr = open("test.log","w")
raise Exception("Dead")
退出后test.log的內容:
Traceback (most recent call last):
File "test.py", line 5, in <module>
raise Exception("Dead")
Exception: Dead
這對我有用:
#!/usr/bin/env python
from __future__ import print_function
import os, os.path, sys, tempfile
old_out = os.dup(sys.stdout.fileno())
old_err = os.dup(sys.stderr.fileno())
with open(os.path.join(tempfile.gettempdir(), "test.log"), "a") as fp:
fd = fp.fileno()
os.dup2(fd, sys.stdout.fileno())
os.dup2(fd, sys.stderr.fileno())
print("Testing")
print('testing errs', file=sys.stderr)
raise Exception("I'm dying")
未來只是為了更干凈地處理具有相同示例的Python2或Python3。 (我還更改了raise語句以實例化異常,字符串已被棄用很長時間了,而Python3則不正確支持這些字符串)。
old_ *值僅表示我們要在使用重定向文件后恢復原始的stdout和/或stderr。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.