subprocessでシェルコマンドの出力をリアルタイムに取得する

久々のメモです。

Pythonでsubprocessを用いてコマンドを実行した際の標準出力を、リアルタイムで取得してきて表示するサンプルプログラムです。良く見られるサンプルプログラムだと、きちんとコマンドが終了してからの出力を変数に取得する方法しか載ってなかったりしますが、以下のページから情報を得ることができました。

http://stackoverflow.com/questions/1606795/catching-stdout-in-realtime-from-subprocess

以下のような使い方をします。

#/usr/bin/python
# -*- codint: utf-8 -*-

import subprocess, time, os, sys
cmd = [sys.executable, 'test_out.py']

p = subprocess.Popen(cmd,
  stdout=subprocess.PIPE,
  stderr=subprocess.STDOUT)

#for line in p.stdout:
#    print line,
for line in iter(p.stdout.readline, b''):
  print(line.rstrip() + " world !!")

引数cmdにわたっている配列を実行します。
この場合は、test_out.pyというスクリプトを実行していますが、以下のような内容になっています。

#/usr/bin/python
# -*- codint: utf-8 -*-

import sys
import time

for i in range(10):
  print ("%d Hello" % (i))
  sys.stdout.flush()
  time.sleep(1)

単に"Hello"を一秒ごとに出力するサンプルです。

これを実行すると、一秒ごとに吐き出された出力をリアルタイムに取得し、編集して出力することができます。

$ python main_out.py 
0 Hello world !!
1 Hello world !!
2 Hello world !!
3 Hello world !!
4 Hello world !!
5 Hello world !!
6 Hello world !!
7 Hello world !!
8 Hello world !!
9 Hello world !!