サブプロセスの実行(修正する)

昨日、メモしておいた通り、
http://d.hatena.ne.jp/Megumi221/20070824#1187939477
で作成したサブプロセスを実行するための関数を修正する。

動作確認の結果、

  • 子プロセスが標準出力へメッセージを書き出すのみであれば、問題なく動作する。
  • 子プロセスがなんらかのエラーで終了する場合、標準エラー出力へ"ERROR"の文字を書き出して終了する仕様になっている。このような子プロセスの実行も問題ない。
  • 子プロセスがwarningメッセージを出力する場合(出力するだけでプロセスは終了しない)、そのメッセージを標準エラーへ書き出すような仕様になっている。つまり、子プロセスはエラー終了しないのであるが、stdoutとstderrへ同時に書き出している。これが動作しない。

この問題点を解決。
現状だと、"While true"ループが無限ループになってしまうようだ。
e.read()を "While true"の中に入れて、エラー終了の判定を明示的にしてみた。

以下、関数の修正結果(一部のみ記述)。

    r, w, e = popen2.popen3(cmd_name)  # (r,w,e)=(stdout, stdin, stderr)

    success = True

    for x in lines:
        w.write(x)
    if lines:
        try:
            w.flush()                 # 子プロセスにlinesの内容を渡す
        except:
            success = False

    while True:
        s = r.readline()      # 子プロセスからの出力を読み込む
        if s == '':         # 出力が終了したときの処理
            break
        if output:
            output.write(s)     # ファイルへ内容を書き込む
        se = e.read()        # 子プロセスの標準エラー出力を読む
        if se:
            if se.find('ERROR') != -1:  # 標準エラーの内容に"ERROR"が含まれていれば...
                output.write(s)      # ファイルへ書き出し
                success = False      # ...子プロセスの実行は失敗と判断
            else:
                print se          # "ERROR"はないから、単なる警告。success=Falseとしない。

    if not success or r.close() or w.close() or e.close():
        success = False
        print 'err> failed %s [%s]' \
                     % (cmd_name, time.ctime(time.time()))
    else:
        print 'inf> done %s [%s]' % (cmd_name, time.ctime(time.time()))
    return success