Python

【Python】subprocessのよく使う奴だけまとめたサンプルコード集

Pythonで別コマンド・別プロセスを実行したい時によく使うsubprocessについて、使用頻度の高い用法をサンプルコード付きでまとめてみました。

1. 基本形

基本はsubprocess.run(<コマンド>)という形で実行します。
コマンドはlist型で指定します。
(例えばls -lは、["ls", "-l"]と指定)

import subprocess

# ls -lを実行
cmd = ["ls", "-l"]
subprocess.run(cmd)

2. 結果取得

終了コード

終了コードは、subprocess.run()の返り値から取得できます。
subprocess.run()を実行すると、CompletedProcessが返されるのですが、
この返り値のreturncode属性にコマンドの終了コードが格納されています。

import subprocess

# ls -lを実行
cmd = ["ls", "-l"]
result = subprocess.run(cmd)

# 終了コードは返り値の.returncodeに格納されている
print("returncode={}".format(result.returncode))
# > returncode=0

標準出力/標準エラー出力

コマンドの結果出力(標準出力/標準エラー出力)を取得したい場合は、capture_output=Trueを指定します。
テキストとして取得する場合はtext=Trueを合わせて指定しておくと便利です。
(text=Trueを指定しない場合はbytes型で返されます)

import subprocess

cmd = ["ls", "-l"]

# capture_output=True, text=Trueを指定
result = subprocess.run(cmd, capture_output=True, text=True)

# .stdoutに標準出力、.stderrに標準エラー出力が格納される
print(result.stdout)
print(result.stderr)

3. 例外処理

終了コードが0以外の時に例外を起こす

終了コードが0以外の時に例外を起こしたい場合は、check=Trueを指定します。
0以外の場合にsubprocess.CalledProcessErrorの例外が発生します。

import subprocess

try:
    cmd = ["ls", "/hoge/fuga"]

    # check=Trueを指定
    result = subprocess.run(cmd, check=True)

except subprocess.CalledProcessError as e:
    # 終了コードが0以外の場合、例外が発生
    print(e)
    # > Command '['ls', '/hoge/fuga']' returned non-zero exit status 1.

コマンドをタイムアウトさせる

コマンドをタイムアウトさせたい場合はtimeoutパラメータを指定します。
タイムアウトした場合、subprocess.TimeoutExpiredの例外が発生し、コマンド(子プロセス)はkill(kill -9)されます

import subprocess

try:
    cmd = ["sleep", "10"]

    # timeout=<秒数>を指定
    result = subprocess.run(cmd, timeout=3)

except subprocess.TimeoutExpired as e:
    # タイムアウトした場合、例外が発生
    # コマンド(子プロセス)はkill(kill -9)される
    print(e)
    # > Command '['sleep', '10']' timed out after 2.999830309 seconds

4. その他

shellのワイルドカード(*)やパイプ(|)を使う

*や|を使いたい場合は、shell=Trueを指定します。
この時、コマンドは文字列として指定しないと想定通りの動作にならないので注意です。

import subprocess

# コマンドは一つの文字列として指定
cmd = "ps aux | grep python3"

# shell=Trueを指定
result = subprocess.run(cmd, shell=True)

※shell injectionの脆弱性が発生しないように気をつけましょう。

標準入力を渡す

標準入力を使用したい場合は、inputパラメータを指定します。
標準出力の時と同様で、テキストを扱う場合はtext=Trueを指定しておくと便利です。

import subprocess

cmd = ["tr", "-d", "x"] # 標準入力から指定の文字("x")を削除するコマンド

# inputに標準入力として渡したい文字列を指定。バイナリで指定する場合はtext=Trueは不要
result = subprocess.run(cmd, input="xyz", text=True)

コメント

タイトルとURLをコピーしました