概要
Pythonで外部コマンドを呼んで標準出力を文字列で取得する。
バージョン情報
- Python 3.6.8
事前準備
標準出力と標準エラーに出力する下記のようなコード(out.py)を用意しておく。
import sys print('standard out') print('standard error', file=sys.stderr)
check_output
check_outputを使うと戻り値に標準出力の結果が返る。
import subprocess subprocess.check_output(['python', 'out.py']) #=> b'standard out\n'
上記ではstdoutの方だけbytesで結果が返っている。stderrorの方は戻り値には入らない。
stderrの出力先を標準出力に向けると双方の結果が返る。
subprocess.check_output(['python', 'out.py'], stderr=subprocess.STDOUT) #=> b'standard error\nstandard out\n'
Popen.communicate
Popen.communicateを使うとより細かくプロセスの制御ができる。
例えば out.py の最後にexit(1)を追加した out2.py というコードを用意した場合。
import sys print('standard out') print('standard error', file=sys.stderr) sys.exit(1)
check_outputでは実行したコードがexit status 0以外を返した場合、CalledProcessErrorがraiseされる。
subprocess.check_output(['python', 'out2.py'])
実行結果
CalledProcessError: Command '['python', 'out2.py']' returned non-zero exit status 1.
これをPopenで開けると、exit statusが0以外でも標準出力の結果が取れる。
proc = subprocess.Popen(['python', 'out2.py'], stdout=subprocess.PIPE) proc.communicate() #=> (b'standard out\n', None) proc.returncode #=> 1
communicate() の戻り値は要素が2つのtupleになっている。左が標準出力、右が標準エラー。
エラーの中身も取る場合は stderr=subprocess.PIPE を指定する。
proc = subprocess.Popen(['python', 'out2.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() #=> (b'standard out\n', b'standard error\n')
コマンドの標準出力を行ごとに取得
Popenに対してcommunicateせずにstdoutを取得することで下記のように行ごとに標準出力を取得可能。
proc = subprocess.Popen(['cat', 'foo.txt'], stdout=subprocess.PIPE) for line in proc.stdout: print(line)
標準エラーを捨てたい場合
check_outputもPopenもエラーは何も指定しないと標準エラーとしてスクリプト実行時に画面に出力される。
これらを表示せずに捨てたい場合は subprocess.DEVNULL を指定する。
check_outputの場合。
subprocess.check_output(['python', 'out.py'], stderr=subprocess.DEVNULL)
Popenの場合。
proc = subprocess.Popen(['python', 'out2.py'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) proc.communicate()
改定履歴
Author: Masato Watanabe, Date: 2019-02-17, 記事投稿