【发布时间】:2011-01-17 13:55:12
【问题描述】:
我一直在编写一个小的 Python 脚本,它使用 subprocess 模块和一个辅助函数来执行一些 shell 命令:
import subprocess as sp
def run(command, description):
"""Runs a command in a formatted manner. Returns its return code."""
start=datetime.datetime.now()
sys.stderr.write('%-65s' % description)
s=sp.Popen(command, shell=True, stderr=sp.PIPE, stdout=sp.PIPE)
out,err=s.communicate()
end=datetime.datetime.now()
duration=end-start
status='Done' if s.returncode==0 else 'Failed'
print '%s (%d seconds)' % (status, duration.seconds)
以下行读取标准输出和错误:
s=sp.Popen(command, shell=True, stderr=sp.PIPE, stdout=sp.PIPE)
out,err=s.communicate()
如您所见,没有使用 stdout 和 stderr。假设我想以格式化的方式将输出和错误消息写入日志文件,例如:
[STDOUT: 2011-01-17 14:53:55] <message>
[STDERR: 2011-01-17 14:53:56] <message>
我的问题是,最 Pythonic 的方法是什么?我想到了三个选项:
- 继承文件对象并覆盖
write方法。 - 使用实现
write的 Delegate 类。 - 以某种方式连接到
PIPE本身。
更新:参考测试脚本
我正在用这个脚本检查结果,保存为test.py:
#!/usr/bin/python
import sys
sys.stdout.write('OUT\n')
sys.stdout.flush()
sys.stderr.write('ERR\n')
sys.stderr.flush()
有什么想法吗?
【问题讨论】:
-
我放弃了。我能够包装(子类化)文件,以便写入添加时间戳和文件标题,但 Popen 在 fds 上工作,我看不到写入发生的位置。看起来它只是
os.execvp,而标准输出句柄在某处很神奇。所以我对 Popen 进行了子类化,但它忽略了传递包装文件和 fd:title 映射的事实。
标签: python design-patterns logging subprocess