「 Python で外部コマンド実行」といえばまっさきに思いつくのは標準ライブラリの subprocess ですが、(私の理解が正しければ) subprocess を使うとコマンドが終了するまでその出力を Python でキャプチャできません。
関連記事:【Python】subprocessを使ってPython上からシェルコマンドを実行する
外部コマンドの出力をある程度リアルタイムに Python でキャプチャしたい場合は asyncio の subprocess 系の機能が有用です subprocess 。 具体的には asyncio.create_subprocess_exec() または asyncio.create_subprocess_shell() を使用します。
ただこの方法で stdout.readline()や stderr.readline()を使用すると、まれに whileループを抜けられないことがあります。 Python 公式ドキュメントにも次のような警告が書かれています。
Warning: Use the
communicate()method rather thanprocess.stdin.write(),await process.stdout.read()orawait process.stderr.read. This avoids deadlocks due to streams pausing reading or writing and blocking the child process.
参考にされる際はご注意ください。
次のコードは Python 公式の asyncio.create_subprocess_exec() のサンプルコード(こちら)を少し変更したものです
import sys
import subprocess
def get_lines(cmd):
'''
:param cmd: str 実行するコマンド.
:rtype: generator
:return: 標準出力 (行毎).
'''
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
line = proc.stdout.readline()
if line:
yield line
if not line and proc.poll() is not None:
break
# コマンド
cmd = "python hello.py"
if __name__ == '__main__':
for i in range(1):
try:
for line in get_lines(cmd=cmd):
sys.stdout.write(line)
except:
pass

コメント