Pythonからコマンドを実行したい場合、subprocessを利用します。
この記事では、subprocessの使い方についてまとめています。
本記事の内容
- subprocessとは?
- subprocessを使ってコマンドを実行する
それでは、上記に沿って解説していきます。
subprocessとは?
最初に、subprocessについて説明します。
subprocessは、Pythonの標準ライブラリです。
つまり、別途ライブラリをインストールする必要がありません。
そして、その主な機能はサブプロセス管理になります。
サブプロセスを生成して、それをkillすることもできます。
「サブプロセス管理=コマンド実行」
上記のように考えることができます。
あと、サブプロセスの呼び出し方には2つのパターンがあります。
- 同期
- 非同期
subprocessでは、上記のように二つの呼び出し方が用意されています。
しかし、個人的には「同期」だけで十分と考えています。
「非同期」でサブプロセスを呼ぶ状況をあまりイメージできません。
重い処理を起動させるためのトリガーとしてなら、「非同期」を使ったことがあります。
まあ、必要となった際に覚えればよいでしょう。
以上、subprocessについての説明でした。
以降では、実際にsubprocessを利用していきましょう。
subprocessを使ってコマンドを実行する
実行するコマンドは、以下とします。
python -V
これなら、WindowsでもLinuxでもどちらでも実行可能です。
もちろん、macOSでも。
呼び出すモジュールは、以下となります。
import subprocess from subprocess import PIPE
サブプロセスの呼び出し方は、「同期」とします。
「同期」で呼び出す場合は、run()関数を利用することになります。
run()関数には、多くのパラメータが用意されています。
今回は、よく利用するモノをピックアップしています。
- shell
- stdout
- stderr
- text
指定した方が便利なパラメータと言う方が、適切かもしれません。
では、以下で説明していきます。
shell
subprocess.run(['python', '-V'])
上記を実行すると、Pythonのバージョンが表示されます。
Python 3.9.4
でも、明らかにコマンドの書き方がオカシイと思いませんか?
shellを指定しないと、リスト形式でコマンドを書く必要があるのです。
では、shellを指定する場合を確認します。
subprocess.run('python -V', shell=True)
上記を実行すると、同じ結果が表示されます。
絶対にこっちの方が、人間に優しい書き方ですよね。
stdout
先ほどから、おかしいと思いませんか?
「print」コマンドを使っていないのに、コマンドの実行結果が表示されています。
コマンドの実行結果は、自分で表示したいです。
戻り値を変数に設定するようにしてみます。
sub_proc = subprocess.run('python -V', shell=True) print("-----") print(sub_proc)
上記を実行すると、以下の結果となります。
Python 3.9.4 ----- CompletedProcess(args='python -V', returncode=0)
どうもまだおかしいです。
コマンド実行結果が、勝手に表示されています。
それにsub_procにコマンド実行結果が格納されていません。
stdoutを指定すれば、sub_procにコマンド実行結果が格納されます。
sub_proc = subprocess.run('python -V', shell=True, stdout=PIPE) print("-----") print(sub_proc)
実行結果は、以下。
----- CompletedProcess(args='python -V', returncode=0, stdout=b'Python 3.9.4\r\n')
同時に、勝手にコマンド実行結果が表示されなくなりました。
sub_procの中のstdoutに結果が入っています。
stderr
stdoutのエラー版です。
sub_proc = subprocess.run('python -W', shell=True, stdout=PIPE) print("-----") print(sub_proc)
上記を実行すると、次のように表示されます。
Argument expected for the -W option usage: python.exe [option] ... [-c cmd | -m mod | file | -] [arg] ... Try `python -h' for more information. ----- CompletedProcess(args='python -W', returncode=2, stdout=b'')
「-W」なんてオプションはないというエラーですね。
このエラーが勝手に表示されています。
stdoutと同じように設定します。
sub_proc = subprocess.run('python -W', shell=True, stdout=PIPE, stderr=PIPE) print("-----") print(sub_proc)
実行結果は、以下。
----- CompletedProcess(args='python -W', returncode=2, stdout=b'', stderr=b"Argument expected for the -W option\r\nusage: python.exe [option] ... [-c cmd | -m mod | file | -] [arg] ...\r\nTry `python -h' for more information.\r\n")
sub_procの中のstderrに結果が入っています。
text
stdout・stderrを設定すると、sub_procの中にコマンド実行結果を格納できました。
ただ、その際に「b」と付いているのに気が付きましたか?
stdout=b'Python 3.9.4\r\n'
これは、byte列型を表しています。
byte列型が安全なのはわかりますが、少し扱いにくいです。
それを文字列にしたい場合は、textを設定します。
sub_proc = subprocess.run('python -V', shell=True, stdout=PIPE, stderr=PIPE, text=True) print("-----") print(sub_proc)
実行結果は、以下。
----- CompletedProcess(args='python -V', returncode=0, stdout='Python 3.9.4\n', stderr='')
「b」が消えて、単なる文字列になりました。
stdout='Python 3.9.4\n'
まとめ
上記のパラメータを利用すれば、ほぼやりたいことはできるでしょう。
Pythonからコマンドを実行して、その結果を利用してということを。
最後に、戻り値(sub_proc)の中の「returncode」について説明しておきましょう。
returncodeが「0」なら、正常にコマンドが実行されたということです。
「0」以外は、正常ではないと考えてよいでしょう。
「python -W」を実行した際は、returncodeは「2」となっています。
よって、returncodeをもとにコマンド実行の結果を判断するとことになります。