6

シェル スクリプトの代わりに、plumbum python ライブラリ (http://plumbum.readthedocs.org/) を使用しています。

実行したいコマンドがあります。失敗すると、興味のあるファイルへのパスが出力されます。

$ 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しかし、例外または将来のオブジェクトからエラー出力を取得できません。

FG でを実行しない場合slow_cmd、例外にはすべての出力が含まれ、そこからファイルを読み取ることができます。

4

1 に答える 1

6

問題は、FG出力をプログラムの stdout に直接リダイレクトすることです。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..."

より洗練された解決策はFG、出力ストリームを複製する独自の ExecutionModifier ( など) を作成することです。それを呼び出しましょうTEEhttp://en.wikipedia.org/wiki/Tee_(command)の後)...私はそれをテストしていませんが、トリックを行う必要があります(selectstdout/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.
于 2013-01-09T08:59:36.290 に答える