簡體   English   中英

使用plumbum捕獲前台命令的錯誤輸出

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM