Python subprocess モジュール

subprocessは Python 標準ライブラリのモジュールであり、サブプロセスの作成と管理に使用されます。

subprocessPython プログラム内で外部コマンドを実行し、それらのコマンドと対話することを可能にします。

このsubprocessモジュールを使用すると、システムコマンドを実行したり、他のプログラムを呼び出したり、それらの出力やエラー情報を取得したりできます。

なぜ subprocess モジュールを使うのか?

Python では、特定のタスクを完了するためにシステムコマンドを実行したり、他のプログラムを呼び出したりする必要がある場合があります。例えば、シェルコマンドの実行、外部アプリケーションの起動、またはコマンドラインツールとの対話が必要になるかもしれません。subprocessモジュールは、これらのニーズに対応するための安全で柔軟な方法を提供します。

初期のos.system() 或 os.popen()と比較して、subprocessモジュールはより強力な機能と優れた制御能力を提供します。サブプロセスの入力、出力、エラーストリームをより細かく管理でき、より複雑なシナリオも処理できます。


subprocess モジュールの核心機能

1. 外部コマンドを実行する

subprocess.run()であるsubprocessモジュールで最もよく使われる関数の1つです。外部コマンドを実行し、コマンドの完了を待ちます。以下は簡単な例です:

実例

import subprocess

# 簡単なシェルコマンドを実行する
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)

# コマンドの出力を表示する
print(result.stdout)

この例では、subprocess.run()実行されたのはls -lコマンドで、その出力はresult.stdoutにキャプチャされました。

2. 入力と出力を処理する

subprocessモジュールを使用すると、サブプロセスの入力、出力、エラーストリームを制御できます。データをサブプロセスの標準入力に渡したり、サブプロセスの標準出力や標準エラーからデータを読み取ったりできます。以下は例です:

実例

import subprocess

# コマンドを実行し、入力をサブプロセスに渡す
result = subprocess.run(['grep', 'python'], input='hello\npython\nworld', capture_output=True, text=True)

# コマンドの出力を表示する
print(result.stdout)

この例では、subprocess.run()実行されたのはgrep pythonコマンドで、文字列'hello\npython\nworld'を入力としてサブプロセスに渡しました。

3. エラーを処理する

subprocessモジュールはサブプロセスのエラー処理も可能にします。サブプロセスがゼロ以外の終了ステータスコードを返した場合、subprocess.run()スローされるのはCalledProcessError例外です。[returncode] を確認することで、result.returncodeサブプロセスの終了ステータスコードを取得できます。

実例

import subprocess

try:
    result = subprocess.run(['ls', 'nonexistent_file'], capture_output=True, text=True, check=True)
except subprocess.CalledProcessError as e:
    print(f"Command failed with return code {e.returncode}")
    print(f"Error output: {e.stderr}")

この例では、subprocess.run()実行されたのはls nonexistent_fileコマンドで、ファイルが存在しないため失敗し、スローされたのはCalledProcessError例外です。


subprocess モジュールの上級用法

1. Popen クラスを使用する

subprocess.Popenクラスはより低レベルのインターフェースを提供し、サブプロセスをより柔軟に制御できます。また、[Popen()] を使用してPopen子プロセスを起動し、バックグラウンドで実行したり、対話したりできます。

実例

import subprocess

# 子プロセスを起動する
process = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE, text=True)

# 子プロセスの出力を読み取る
while True:
    output = process.stdout.readline()
    if output == '' and process.poll() is not None:
        break
    if output:
        print(output.strip())

# 子プロセスの終了ステータスコードを取得する
return_code = process.poll()
print(f"Process finished with return code {return_code}")

この例では、subprocess.Popen起動されたのはping google.comコマンドで、バックグラウンドで実行されました。プログラムはループを使用して子プロセスの出力を読み取り、子プロセスが終了した後にその終了ステータスコードを取得します。

2. パイプを使用する

subprocessモジュールを使用すると、パイプを使って複数のコマンドを接続できます。あるコマンドの出力を別のコマンドの入力として渡せます。

実例

import subprocess

# パイプを使用して2つのコマンドを接続する
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'py'], stdin=p1.stdout, stdout=subprocess.PIPE, text=True)

# 最終出力を取得する
output = p2.communicate()[0]
print(output)

この例では、ls -lコマンドの出力はgrep pyコマンドに渡され、最終出力にはpyのファイルまたはディレクトリが含まれます。


subprocess モジュールの一般的なメソッド、クラス、パラメータ

以下は、Python subprocessモジュールの一般的なメソッド、クラス、パラメータの説明で、機能の説明と例を含みます:

subprocess モジュールの核心メソッド

メソッド説明例
subprocess.run()コマンドを実行して完了を待つ(推奨)subprocess.run(["ls", "-l"], capture_output=True, text=True)
subprocess.Popen()サブプロセスを作成する(低レベル制御)proc = subprocess.Popen(["ping", "google.com"], stdout=subprocess.PIPE)
subprocess.call()コマンドを実行して終了コードを返す(旧版)exit_code = subprocess.call(["python", "--version"])
subprocess.check_call()コマンドを実行し、失敗時に例外をスローするsubprocess.check_call(["git", "commit"])
subprocess.check_output()コマンドを実行して出力を返す(旧版)output = subprocess.check_output(["date"], text=True)

subprocess.CompletedProcess オブジェクトの属性(run() メソッドの戻りオブジェクト)

属性説明
args実行されたコマンドの引数リスト
returncodeプロセスの終了ステータスコード(0は成功を意味します)
stdout標準出力の内容(設定されている場合capture_output)
stderr標準エラーの内容(設定されている場合capture_output)

subprocess.Popen クラスの一般的なメソッド/属性

メソッド/属性説明例
poll()プロセスが終了したかどうかを確認(戻り値がNoneの場合は実行中)if proc.poll() is None: print("Running")
wait()ブロックしてプロセスの終了を待つproc.wait()
communicate()対話式の入力/出力stdout, stderr = proc.communicate(input="data")
terminate()終了シグナル(SIGTERM)を送信するproc.terminate()
kill()プロセスを強制終了する(SIGKILL)proc.kill()
stdinプロセスの標準入力ストリームproc.stdin.write("input")
stdoutプロセスの標準出力ストリームprint(proc.stdout.read())
stderrプロセスの標準エラーストリームerrors = proc.stderr.read()

一般的なパラメータの説明(run() と Popen() に適用)

パラメータ説明例の値
argsコマンド(リストまたは文字列)["ls", "-l"] 或 "ls -l"
stdin標準入力の設定subprocess.PIPE(パイプ)、None(継承)
stdout標準出力の設定subprocess.PIPE、open('log.txt', 'w')
stderr標準エラーの設定subprocess.STDOUT(stdoutに統合)
shellShellを介して実行するかどうかTrue(文字列コマンドをサポート)
cwd作業ディレクトリのパス"/tmp"
envカスタム環境変数{"PATH": "/usr/bin"}
timeoutタイムアウト時間(秒)30
text入出力が文字列かどうか(バイトではない)True

実例

コマンドを実行して出力をキャプチャする:

実例

result = subprocess.run(["echo", "Hello"], capture_output=True, text=True)
print(result.stdout)  # 出力: "Hello\n"

Shellを介して複雑なコマンドを実行する:

subprocess.run("grep 'error' log.txt | wc -l", shell=True, check=True)
出力ストリームをリアルタイムで取得する:

実例

proc = subprocess.Popen(["tail", "-f", "log.txt"], stdout=subprocess.PIPE)
while True:
    line = proc.stdout.readline()
    if not line: break
    print(line.decode().strip())

タイムアウト制御:

実例

try:
    subprocess.run(["sleep", "10"], timeout=5)
except subprocess.TimeoutExpired:
    print("コマンドがタイムアウトしました!")
その他の拡張