Pythonで標準入力を受け取る
Pythonスクリプト間で標準入出力を使ってデータのやり取りをしてみる。
まずは標準入力を受け取る方法。sys.stdin.read()
を使う。
$ cat stdin.py
#!/usr/bin/env python
import sys
stdin_str = sys.stdin.read()
print stdin_str
$ echo -n test | ./stdin.py
test
Pythonのスクリプト内で別のPythonスクリプトを呼び出すときの標準入出力
先の例では標準入力はshell上から渡したが、Pythonのスクリプト内で別のPythonスクリプトを呼び出し、そのときに標準出力を与える方法を書く。
$ cat call_other.py
#!/usr/bin/env python
import os
import subprocess
other_script = os.path.join(os.path.abspath(os.path.dirname(__file__)), "stdin.py")
proc = subprocess.Popen(other_script, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdout_str = proc.communicate("test")[0]
print stdout_str
$ ./call_other.py
test
subprocess.PIPE
で標準入出力先にパイプが繋がるようになる。subprocess
のcommunicate()
の引数に文字列を渡すことで自身のスクリプトから標準出力を外部プログラムへ渡すことができ、また外部プログラムの標準出力もcommunicate()
の戻り値のはじめの要素から得られる。
ちなみにcommunicate()
の戻り値は(stdout_data, stderr_data)
なので、stderr=subprocess.PIPE
をsubprocess.Popen()
で設定していれば、戻り値の二つ目の要素から標準エラー出力が得られる。
Python 3系の場合の標準入出力
Python 3系の場合はcommunicate
の引数、戻り値ともにencode
, decode
しなければならない。あるいはencoding
を指定して読み込む。さらにContext Managerがサポートされているのでwith
を使う。
encode
, decode
を使う場合
other_script = os.path.join(os.path.abspath(os.path.dirname(__file__)), "stdin.py")
with subprocess.Popen(other_script, stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc
stdout_str = proc.communicate("test".encode())[0].decode()
encoding
を指定する場合
other_script = os.path.join(os.path.abspath(os.path.dirname(__file__)), "stdin.py")
with subprocess.Popen(other_script, stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding="utf-8") as proc
stdout_str = proc.communicate("test")[0]