[英]Capture the error output of a foreground command using plumbum
我使用plumbum python库(http://plumbum.readthedocs.org/)作为shell脚本的替代品。
有一个我想要运行的命令,当它失败时它会输出我感兴趣的文件的路径:
$ slow_cmd
Working.... 0%
Working.... 5%
Working... 15%
FAIL. Check log/output.log for details
我想在前台运行程序来检查进度:
from plumbum.cmd import slow_cmd
try:
f = slow_cmd & FG
except Exception, e:
print "Something went wrong."
# Need the error output from f to get the log file :(
当slow_cmd
失败时,它会抛出异常(我可以捕获)。 但我无法从异常或f
future对象获取错误输出。
如果我没有在FG上运行slow_cmd
,则异常包含所有输出,我可以从那里读取文件。
问题是, FG
将输出直接重定向到程序的标准输出。 请参阅https://github.com/tomerfiliba/plumbum/blob/master/plumbum/commands.py#L611
当输出以这种方式重定向时,它不会通过plumbum的机器,所以你不会在异常对象中得到它。 如果你愿意阻止,直到slow_cmd
完成,一个更好的解决方案是自己读取stdout。 这是草图:
lines = []
p = slow_cmd.popen()
while p.poll() is None:
line = p.stdout.readline()
lines.append(line)
print line
if p.returncode != 0:
print "see log file..."
更优雅的解决方案是编写自己的ExecutionModifier(如FG
),复制输出流。 让我们称之为TEE
(在http://en.wikipedia.org/wiki/Tee_(command)之后 )...我还没有测试过它,但它应该做的伎俩(减去select
stdout / err):
class TEE(ExecutionModifier):
def __init__(self, retcode = 0, dupstream = sys.stdout):
ExecutionModifier.__init__(self, retcode)
self.dupstream = dupstream
def __rand__(self, cmd):
p = cmd.popen()
stdout = []
stderr = []
while p.poll():
# note: you should probably select() on the two pipes, or make the pipes nonblocking,
# otherwise readline would block
so = p.stdout.readline()
se = p.stderr.readline()
if so:
stdout.append(so)
dupstream.write(so)
if se:
stderr.append(se)
dupstream.write(se)
stdout = "".join(stdout)
stderr = "".join(stderr)
if p.returncode != self.retcode:
raise ProcessExecutionError(p.argv, p.returncode, stdout, stderr)
return stdout, stderr
try:
stdout, stderr = slow_cmd & TEE()
except ProcessExecutionError as e:
pass # find the log file, etc.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.