Raspberry Pi & Python 開発ブログ ☆彡

Raspberry PiとPythonの基本的な使い方をわかりやすく解説。初心者、入門者必見!!

pythonからシェルコマンドを実行する

今回は、pythonプログラムからシェルコマンドを実行する方法を紹介します。subprocessというモジュールを使用します。今まで、os.systemモジュールを使用していましたが、ドキュメントを見ると非推奨となっていますので、subprocessモジュールに置き換えていこうと思っています。

subprocess.callを使用して、シェルコマンドを実行

シェルコマンドの戻り値が必要ない場合は、このcallというコマンドが手っ取り早く、シェルコマンドを実行できます。callの引数にシェルコマンドを記載するだけです。shlexモジュールでコマンドをトークン化してくれます。

import subprocess, shlex

args = shlex.split("mkdir ./test")
ret = subprocess.call(args)
print(ret)

これで、カレントフォルダにtestフォルダが作成されます。戻り値、正常終了であれば、ret = 0、異常終了であれば、ret=1となります。

import subprocess, shlex

args = shlex.split("sudo shutdown -h now")
ret = subprocess.call(args)

上記プログラムで、Raspberry Piがシャットダウンします。

subprocess.runを使用して、シェルコマンドを実行

subprocess.runコマンドを使えば、標準出力(戻り値)、エラー出力が取得できます。ドキュメントでも推奨されています。

import subprocess, shlex

args = shlex.split("ls -al")
ret = subprocess.run(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(ret.returncode)    # 終了コード
print(ret.stdout.decode("utf-8"))    # 標準出力
print(ret.stderr.decode("utf-8"))    # エラー出力

戻り値はバイトコードで返ってきますので、utf-8に変換する必要があります。 runコマンドでほとんどの場合は、事足りると思います。

subprocess.Popenを使用して、シェルコマンドを実行

上記のsubprocess.runコマンドでは、実行から出力取得まで一連動作を一気に行います。その間、他の処理をすることができません。subprocess.Popenは実行と出力取得を分けて実行することができますので、その間に別の処理を実行することができます。

import subprocess, shlex

args = shlex.split("時間がかかるコマンド") 
proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE) # (1) シェルコマンド実行

# subprocessとは別の処理 (2)

try:
    outs,errs = proc.communicate(timeout=15) # (3) シェルコマンドの出力取得
except TimeoutExpired:    # 15秒タイムアウトで例外処理
    proc.kill()
    outs,errs = proc.communicate()

print("stdout:" + outs.decode("utf-8"))    # 標準出力
print("stderr:" + errs.decode("utf-8"))    # エラー出力

subprocessの使い方は以上になります。

ラズパイ ソフトウェアに戻る
トップページに戻る