このまえ、os.system関数で外部コマンドを実行するやり方を書いたけど、どうもsubprocessモジュールを使うやり方のほうが新しいらしい。subprocessモジュールの Popenクラスを使うと、子プロセスにデータを送ったり、結果を受け取ったりできる。
cf. http://docs.python.jp/2.7/library/subprocess.html
まずは、結果を受け取る方法から。
import subprocess p = subprocess.Popen("ls *.py", stdout=subprocess.PIPE) files = p.communicate()[0].split("\r\n") for file in files: print file
subprocess.Popenオブジェクトを作るには、第1引数にコマンドを指定する。結果を受け取るにはstdout=subprocess.PIPE を指定しておく。で、communicateメソッドで結果を取得する。
実行結果:
^o^ > python test_subprocess.py argv.py bubble_sort.py count_files.py counting_sort.py csv_read.py csv_write.py default_arg.py dict.py dict_keys.py dictionary.py enumerate.py exception1.py exception2.py exception3.py false.py fib.py (以下略)
次に、子プロセスにデータを渡す方法。supbrocess.Popenオブジェクトを作るときに、stdin=subprocess.PIPEを指定しておいて、communicateメソッドの引数としてデータを渡す。
import subprocess p = subprocess.Popen("python file_input.py", stdin=subprocess.PIPE) data = open("sample.txt", "r").read() p.communicate(data)
実行結果:
^o^ > python test_subprocess2.py <stdin> 1 : Mon <stdin> 2 : Tue <stdin> 3 : Wed <stdin> 4 : Thu <stdin> 5 : Fri <stdin> 6 : Sat <stdin> 7 : Sun
期待通りの出力が得られた。
最後に両方をやってみよう。
import subprocess p = subprocess.Popen("python file_input.py", stdin=subprocess.PIPE, stdout=subprocess.PIPE) data = open("sample.txt", "r").read() output = p.communicate(data)[0] for line in output.split("\r\n"): print line
実行結果:
^o^ > python test_subprocess3.py <stdin> 1 : Mon <stdin> 2 : Tue <stdin> 3 : Wed <stdin> 4 : Thu <stdin> 5 : Fri <stdin> 6 : Sat <stdin> 7 : Sun
上のと同じ出力だけど、これは子プロセスから結果を受け取ったPythonスクリプトが出力したもの。