Pythonは、さまざまな機能が用意されているプログラミング言語ですが、
他のプログラムやコマンドを実行する機能も持っていることをご存知でしょうか?
たとえば、”C++で作ったexeを実行したいなぁ”とか
“過去に作ったPythonの処理が使いたいなぁ”とか。
そんな願いをかなえてくれるステキなモジュールがsubprocessです。
本記事では、subprocessの使い方について解説していきます。
Pythonのみではなく、他のプログラムも自由にあやつる術をマスターしましょう!
subprocessモジュールとは?
subprocess
モジュールは、
Pythonからコマンドや他のプログラムを実行するためのツールです。
プログラム言語ごとに得意とする処理を書き、
それぞれを1つの処理の中で実行することも可能となります。
全ての処理をPythonだけで考える必要がなくなります。
今まで経験してきたプログラム言語もそのまま活用できますよ~
基本的な使い方
基本的なコードの紹介
使用するのは、subporocess.run
のコードです。
書き方は、subprocess.run([実行コマンド], オプション1, オプション2, ...)
のような形式をとります。
さっそく例を見ていきましょう。
以下は、echo 'Hello, World!'
というコマンドを実行する例です。
import subprocess
# 'echo Hello, World!' コマンドを実行.
result = subprocess.run(['echo', 'Hello, World!'], shell=True)
echo 'Hello, World!'
は、echo
と'Hello, World!'
が
スペースで区切られたコマンドです。
スペースで区切られた単位で['echo', 'Hello, World!']
のようなリストを作り、
subprocess.runの引数に入れることで、実行することができます。
他のどんなコマンドでも同じルールで実行できます。
長いコマンドだと書くのが大変ですね
subprocess.runの返り値
subprocess.CompletedProcess
が返り値として、取得できます。
中身の要素は、以下の4点です。
返り値 | 説明 |
---|---|
args | 実行したコマンドを取得 |
returncode | 実行したコマンドの終了コード 0:正常、0以外:エラー発生 |
stdout | 標準出力をバイト形式で取得 ※capture_outputやstdoutのオプションの設定が必要。 |
stderr | 標準エラーをバイト形式で取得 ※capture_outputやstderrのオプションの設定が必要。 |
実行したコマンドをログに出したり、
エラー調査や動作確認に使用したりと全部よく使いますね!
主なオプションの紹介
必要なオプションを選択して、便利に使っていきましょう。
よく使用する5点を紹介します。
オプション | 説明 |
---|---|
shell | システムのシェル※1を通じてコマンドを実行。subprocess.run(["echo", "Hi!"], shell=True) |
cwd | コマンド実行時のディレクトリを指定。subprocess.run(["echo", "Hi!"], cwd="/path/to/directory") |
check | コマンドがエラーを返した場合に例外をスロー。subprocess.run(["false"], check=True) |
capture_output | 標準出力(stdout)と標準エラー(stderr)をキャプチャ。r=subprocess.run(["echo", "Hi!"], capture_output=True) |
text | コマンドの出力をバイト形式からテキスト形式に変換して取得。r=subprocess.run(["echo", "Hi!"],capture_output=True, text=True) |
※1 シェル:コンピュータとユーザーの間でコマンドを受け取り実行するプログラムのこと。
windowsならコマンドプロンプト(cmd.exe)やPowershellや、Linuxならbashなど。
ユーザに見せたくないログを出す場合は、
リリース版ではOFFにすると良いですね。
エラー処理
不正なコマンドを実行した際のエラー処理も可能です。check=True
をつけると、エラーが生じた時に例外を発生させてくれます。
【サンプルコード】
import subprocess
try:
# 存在しないコマンドを実行してエラーを確認.
subprocess.run(['nonexistent_command'], shell=True, check=True)
except subprocess.CalledProcessError as e:
print("エラーが発生しました:", e)
【実行結果】
'nonexistent_command' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
エラーが発生しました: Command '['nonexistent_command']' returned non-zero exit status 1.
非同期実行 : 同時に複数のプログラムを実行!
せっかく他の処理を呼び出せるのですから、
何個も同時に実行したい場合もありますよね。
たとえば、データの集計プログラムを1000個のファイルに対して実行したいときに、
1個づつ対応すると時間がかかります。
そんなときに便利なのが、subprocess.Popen
を利用した非同期処理です。
複数の処理を並列に実行することができるので、作業スピードも向上することでしょう!
少し難しい内容となっているので、
高速化に興味のあるかたは以下の記事を確認してみてください!
※別記事に準備中
並列に実行しすぎても、処理負荷が高くなる場合があるので注意です!
同時に処理する個数は決めておくと良いですね。
他のPythonプログラムの実行方法
subprocessでは、他のPythonのプログラムファイルを指定して実行することもできます。
ですが、『同じPythonならモジュールとしてimportして使えばいいのでは?』と
疑問を持つかたもいるはずです。
モジュールとsubprocessにはそれぞれのメリットがあるので、
使い分けについてもチェックしていきましょう!
Pythonプログラムの実行方法
ターミナルからPythonのプログラムを実行するコマンドを、
subprocessの引数に設定すればOKです。
import subprocess
# 'sample.py' コマンドを実行.
result = subprocess.run(['python', 'sample.py'], shell=True)
subprocessとモジュールを使い分ける判断基準
subprocessとモジュールは、外部にあるプログラムとの橋渡しをしてくれる点では
同じ役割であり、コードの再利用性を高めてくれます。
では、違う点はどこにあるか。
それぞれの特徴を見ていきましょう。
比較項目 | subprocess | モジュール |
---|---|---|
実行対象 | Pythonを含めた外部のプログラム。 | Pythonのみ。 |
実行方法 | 新しいプロセスを作成して実行。 | 1つのプロセスで全て実行。 |
実行環境 | 外部プログラムに依存。 | Pythonのみ。 |
セキュリティ | 外部プログラムによる危険性への 注意も必要。 | 比較的安全。 Python外による危険性が少ない。 |
エラー処理 | 実行時に処理ごとに検知が必要。 エラーハンドリングも個別に必要。 | Pythonの例外処理を使用可能。 |
ざっくりまとめると、subprocessの方ができることは多いけど、
セキュリティやエラーなど対応する面倒事も多くなります。
ですので、可能であればモジュールとして使用する方が良いでしょう。
モジュールでできないことを行う場合にsubprocessを使用していきましょう!
コマンドの実行方法
windowsやLinuxなどで実行するコマンドは、
権限がついてないもの等を除いて、全てPythonから実行することができます。
import subprocess
# lsコマンドを実行(Linux系OS).
result = subprocess.run(['ls'], shell=True)
# dirコマンドを実行(Windows系OS).
result = subprocess.run(['dir'], shell=True)
モジュールを含めて考えると、
コマンドにできて、Pythonでできないこと自体はほとんどありません。
しかし、複数のPCで同じプログラムを使用したい時に、
モジュールは各環境にインストールしないと起動しません。
その点、コマンドはOSに含まれることが多いため、作業コストは少なくなるでしょう。
また、OSによって使えるコマンドは変わるので、
Pythonを中継することでOS間の場合分けを行うことができるのも利点と言えるでしょう!
メリット・デメリットは上手く組み合わせて、
良い感じに使っていきたいですね!
実行ファイル(.exe)の呼び出し方
ほぼ全てのプログラム言語は、~.exeのような実行ファイルを作成することができます。
ですので、実行ファイルの呼び出し方さえわかれば、
全てのプログラムの処理を実行できるといっても過言ではないでしょう!
たとえばexeであれば、以下のように呼び出すことができます。
import subprocess
# 'sample.exe' を実行.
result = subprocess.run(['sample.exe'], cwd='C:\\Python\\sample', shell=True)
実行ファイルは、自作したもの以外でも実行できます。
たとえば、エディタとして有名なVisualStudio Codeやサクラエディタなども、
exe形式で実行ファイルを持っているので、プログラムから立ち上げることも可能です。
PCを立ち上げた後に、すぐに起動したいアプリをまとめておくと、
1回の実行で全て立ち上げる事もできそうですね!
まとめ
今回は、subprocessのモジュールについて解説しました。
他のプログラムを実行できるため、実装の幅を格段に広げてくれますね。
プログラムを続けていると、”他で作った処理を使いたい!”と思うことは、
よくありますので、そんな時にはドンドン使っていきましょう!
おわり