Python モジュール: subprocess

  • 複数のプロセスを制御するモジュール
  • 以下の場合に使う
    • 関数を別プロセスで並列で処理したい
    • 外部プログラムを呼び出したい

モジュールの定義

import subprocess

プロセス実行メソッド

  • プロセス実行メソッドは大きく分けて run()Popen() がある。
    subprocess.run(COMMAND, OPTIONS)
    subprocess.Popen(COMMAND, OPTIONS)
  • Popen()run() より細かな制御ができる。
  • run() には、旧メソッドの call()check_all()check_output() が統合されている。
  • run()Popen() の共通オプション
    • shell=True|False (デフォルトは False):
      • True の場合、実行コマンド COMMAND を linux のコマンドのように文字列で与える。
        • 引数の区切りをスペースとしているため、スペースを含む引数を与えると、誤認識する。
      • False の場合、実行コマンド COMMAND をリストで与える。
        • ワイルドカードでの指定ができなくなる。
    • stdin=open(FILE_NAME, “rb”): コマンドの標準入力に FILE_NAME から読み出したデータを与える。
    • stdout=open(FILE_NAME, “wb”): コマンドの標準出力を FILE_NAME に書き出す。
    • stderr=open(FILE_NAME, “wb”): コマンドの標準エラーを FILE_NAME に書き出す。
    • stdinstdoutstderr について
      • ファイルの扱いは byte 型の方が問題が起こりにくい。
      • open() の代わりに、subprocess.PIPE を指定すると、画面に出力する。
      • open() の代わりに、subprocess.DEVNULL を指定すると、出力を破棄する。
    • timeout=X: タイムアウトの秒数 X を指定する (ネットワークを利用するコマンド)。
    • text=True|False: PIPE で取得したデータをテキスト型として出力する (デフォルトは False でバイト型)。
    • run() を単純に実行する場合:
      import subprocess
      obj_proc=subprocess.run(["ls", "-l"])
    • ファイルに結果を出力する場合:
      import subprocess
      obj_proc=subprocess.run(["ls", "-l"], stdout=open("test.log", "w"))
    • Popen() を使う場合:
      import subprocess
      obj_proc = subprocess.Popen(["ls", "-l"], stdout=open("test.log", "w"))
    • Popen() で画面に出力を表示する場合:
      import subprocess
      obj_proc = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE, text=True)
      obj_proc.communicate()

run() と旧メソッドの違い

終了ステータス 出力結果 エラー例外
run() での引数や属性 .returncode .stdout check
call()
check_call()
check_output()
  • 旧メソッドは現在でも使えるが、run() のオプションを切り替えることで同じ挙動になる。

Popen.communicate()

  • 標準出力、標準エラーをタプルにして返す。
  • 標準出力、標準エラーの出力量が多い場合、run() では処理できなくなるので、このメソッドを使うことになる。
  • リアルタイムの出力管理や対話処理は扱えない。