subprocessで subprocess.PIPE
を使って標準出力を取得できますが、Consoleには表示されなくなります。
Consoleにリアルタイムに表示しつつ str
として取得したかったので、やり方を調べてみました。
--追記--
yield
を使ったこっちの方が良い。
Code
import sys
import subprocess
def run_and_capture(cmd):
'''
:param cmd: str 実行するコマンド.
:rtype: str
:return: 標準出力.
'''
# ここでプロセスが (非同期に) 開始する.
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
buf = []
while True:
# バッファから1行読み込む.
line = proc.stdout.readline()
buf.append(line)
sys.stdout.write(line)
# バッファが空 + プロセス終了.
if not line and proc.poll() is not None:
break
return ''.join(buf)
if __name__ == '__main__':
msg = run_and_capture('du ~/')
print msg
説明
-
subprocess.Popen(cmd, ...)
でプロセスを開始する-
stderr=subprocess.STDOUT
でstderrをstdoutへ一纏めにする -
stdout=subprocess.PIPE
で標準出力をパイプする
-
-
Popen.stdout.readline()
でパイプした標準出力を1行ずつ取得&出力する - パイプした標準出力をすべて回収 + プロセスが完了するまで待つ
-
''.join(buf)
で文字列結合する