popen2モジュールを使ったサブプロセスの実行(エラー出力がある場合)

今回もpopen2.popen3(cmd)でサブプロセスを実行する。昨日のcmd_wrapper.pyで実行したコマンドでは、標準出力だけに結果を吐き出していたが、今回は標準エラー出力にも結果(エラーメッセージ)を出力するコマンドを実行する。

cmd_wrapper.pyでそのまま実行しようとすると、途中でプロンプトが帰ってこなくなる。その症状から判断すると、どうもエラーメッセージをどこに出力していいか分からずに固まっているようである。あれこれ検討した結果、次のようにしたらうまくいった(cmd_wrapper2.pyを以下に示す)。

#!/usr/bin/env python

""" wrapper for program "cmd2"
"""
import sys
import popen2

def execmd(cmd_name, lines, output):
    """ start sub-process """
    r, w, e = popen2.popen3(cmd_name)

    for x in lines:
        w.write(x)
        w.flush()

    while True:
        s = r.readline()
        if s == '':
            break
        if output:
            output.write(s)

        s = e.read()
#        if s:
#            print s

if __name__ == "__main__":

    cmd_name = 'cmd2'
    output = 'log.%s' % cmd_name

    fl_name1 = 'dummy.file'
    val_dist = 0
    val_conf = 1

    lines = []
    lines.append("%s\n" % sys.argv[1])
    lines.append("%s\n" % sys.argv[2])
    lines.append("%s\n" % fl_name1)
    lines.append("%s\n" % val_dist)
    lines.append("%s\n" % val_conf)

    fd = open(output, 'w')
    execmd(cmd_name, lines, fd)

実行するコマンド名はcmd2とする。cmd_wrapper.pyで実行しているコマンドとは、必要な引数が異なる。実行結果を標準出力(r)へ、エラーメッセージをエラー出力(e)へ吐き出す。

s=e.read()

の行を加えたら正常に実行できた。

今回は特にエラーメッセージを見る必要はないので、勝手に捨ててくれてもいいのに、そうはいかないようだ。この行の存在意義が今ひとつ分からないが、こうゆうものだということは分かった。

ちなみに、if __name__ == "__main__"はいらない。取る場合には以後のインデントをなくすこと。