⚙️ PythonコードからOSコマンドを直接動かせる
フォルダの作成、ファイル一覧の取得、プロセスの管理、アクセス権の付与——ターミナルやコマンドプロンプトで手作業していた操作が、Pythonスクリプト1本に統合できます。subprocessモジュールを使えば、WindowsのコマンドプロンプトでもMac/LinuxのターミナルでもOSのシェルコマンドをPythonから直接呼び出せるようになります。バッチ処理スクリプトとPythonコードを組み合わせたい場面で、特に威力を発揮します。
📌 subprocessモジュールとは?
subprocessは、PythonコードからOSのシェルコマンドを実行できる標準モジュールです。WindowsならコマンドプロンプトやPowerShell、Mac/Linuxならターミナル(bash/zsh)で打ち込んでいたコマンドを、Pythonスクリプト内から呼び出せます。
標準モジュールなので、pip install は不要で import subprocess だけで使えます。
🤔 どんな場面で使うのか
- 🗂️ ディレクトリの作成・削除・一覧取得
- 🔐 フォルダのアクセス権付与などOS管理操作
- 🔄 他のプロセスの起動・停止
- 🖥️ PowerShellスクリプトやbashスクリプトの呼び出し
- 📦 Pythonで書くより、コマンドで書いた方が簡潔な処理
💡 フォルダ作成やファイル操作だけなら
osモジュールやpathlibでも実現できます。subprocessの出番は「シェルコマンドで書いた方がラク」「外部ツールをPythonから呼びたい」と感じたときです。
💻 基本の使い方:subprocess.run()
subprocess.run() が最もシンプルで汎用的な関数です。第1引数にコマンド文字列を渡し、shell=True を指定するだけでコマンドが実行されます。
① ディレクトリを作成する(mkdir)
import subprocess
# Windowsの例:testというフォルダを作成
subprocess.run("mkdir test", shell=True)
このコードを実行すると、Pythonスクリプトと同じ階層に test フォルダが作成されます。たったこれだけです。
② 実行結果を取得する(stdout・returncode・stderr)
コマンドの出力をPython側で受け取りたい場合は、capture_output=True と text=True を追加します。戻り値の CompletedProcess オブジェクトから各種情報を取り出せます。
import subprocess
# testフォルダ内のファイル一覧を取得(Windows)
cp = subprocess.run(
r"dir .\test",
shell=True,
capture_output=True,
text=True
)
print(cp.stdout) # コマンドの標準出力(文字列)
print(cp.returncode) # 正常終了なら 0、エラーなら 0以外
print(cp.stderr) # エラーメッセージ(なければ空文字)
📋 CompletedProcessオブジェクトの主なプロパティ
- 🟢 stdout:コマンドの標準出力を文字列で取得(
text=True時) - 🔢 returncode:正常終了 →
0、エラー →0以外の整数 - 🔴 stderr:エラーメッセージを文字列で取得
存在しないディレクトリに対してコマンドを実行すると、returncode は 0 以外になり、stderr にエラーメッセージが格納されます。この値を使って「コマンド成功時だけ次の処理を実行する」といった分岐が書けます。
⏱️ タイムアウトの設定と例外処理
コマンドが長時間応答しないケースに備えて、timeout 引数で実行時間の上限を設定できます。指定秒数を超えると subprocess.TimeoutExpired 例外が発生するので、try/except で捕捉します。
import subprocess
try:
cp = subprocess.run(
"some_long_command",
shell=True,
capture_output=True,
text=True,
timeout=5 # 5秒でタイムアウト
)
print(cp.stdout)
except subprocess.TimeoutExpired:
print("タイムアウトしました。処理を中断します。")
たとえばキー入力待ちで止まってしまうコマンドなど、Pythonプログラムが無限待機に陥る危険を防げます。
🪟 PowerShellコマンドを実行する(Windows)
WindowsでPowerShellのコマンドをsubprocessから呼び出すには、powershell -command "..." の形式で第1引数に指定します。パスにバックスラッシュが含まれる場合は raw文字列プレフィックス r を付けておくと安全です。
import subprocess
cp = subprocess.run(
r'powershell -command "Get-ChildItem C:\Users"',
shell=True,
capture_output=True,
text=True
)
print(cp.stdout)
PowerShellコマンドを二重引用符で囲み、run()の引数全体はシングル引用符で囲むのがポイントです。
🍎 Mac/Linuxでの使い方
Mac/Linuxでも書き方はほぼ同じです。コマンドをbash/zsh用に変えるだけで動作します。
import subprocess
# Mac/Linux:カレントディレクトリのファイル一覧
cp = subprocess.run(
"ls -la ./test",
shell=True,
capture_output=True,
text=True
)
print(cp.stdout)
✅ subprocess.run() よく使う引数チートシート
- 🔹 shell=True:シェル経由でコマンドを実行(文字列形式で渡す場合に必須)
- 🔹 capture_output=True:stdout・stderrをPythonで受け取れるようにする
- 🔹 text=True:stdout・stderrをバイト列ではなく文字列で受け取る
- 🔹 timeout=秒数:指定秒数を超えたら TimeoutExpired 例外を発生させる
- 🔹 cp.stdout:コマンドの標準出力(文字列)
- 🔹 cp.returncode:終了コード(0=正常、0以外=エラー)
- 🔹 cp.stderr:エラーメッセージ(文字列)
🖥️ 快適な開発環境づくりにおすすめのアイテム
バッチ処理スクリプトやOS操作の自動化は、複数のターミナルウィンドウを並べて作業することが多くなります。広い画面とキーボード環境を整えるだけで、開発効率が大きく変わります🚀
❓ よくある質問 FAQ
🤔 Q1. shell=True と shell=False の違いは何ですか?
shell=True にすると、コマンドをシェル(cmd.exeやbash)経由で実行します。パイプ(|)やワイルドカード(*)などシェル機能が使えます。shell=False(デフォルト)では、コマンドをリスト形式(["ls", "-la"])で渡して直接実行します。信頼できないユーザー入力をコマンドに含める場合は、セキュリティ上 shell=False の方が安全です。
🤔 Q2. capture_output=True を付けないと標準出力はどうなりますか?
capture_output を指定しない場合、コマンドの出力はそのままターミナル画面に表示されますが、Python変数として受け取ることはできません。cp.stdout は None になります。Python側で出力を処理・加工したい場合は必ず capture_output=True と text=True を指定してください。
🤔 Q3. returncode が 0 以外の値を確認する方法はありますか?
subprocess.run() に check=True を追加すると、returncode が 0 以外のとき自動で subprocess.CalledProcessError 例外を発生させられます。try/except subprocess.CalledProcessError でまとめてエラー処理を書けるので、returncode を自分でチェックする手間が省けます。
🤔 Q4. Popen と run() はどう違いますか?
subprocess.run() はコマンドの完了を待ってから制御を返す「同期実行」です。一方 subprocess.Popen() はコマンドを非同期で起動し、Pythonコードと並行して処理できる「非同期実行」に対応しています。複数のコマンドを同時に走らせたい場合や、コマンドの実行中にPython側で別の処理を続けたい場合は Popen を使います。
🤔 Q5. Windowsのコマンドプロンプトとbashで同じコードを使えますか?
使えません。コマンド文字列はOS固有のものになります。クロスプラットフォームで動かしたい場合は、sys.platform や platform.system() でOSを判定し、分岐してコマンドを切り替える方法が一般的です。または、ファイル操作の範囲なら pathlib や shutil モジュールを使ってOS差異を吸収する方が堅牢です。
🎯 まとめ
subprocessモジュールの基本は「subprocess.run(コマンド文字列, shell=True)」の一行から始まります。capture_output=True と text=True を加えれば出力を文字列として受け取れ、returncode でコマンドの成否を確認、timeout でハングアップを防げます。PythonコードとシェルコマンドをうまくミックスさせることでOS操作の自動化がさらに強力になります。シェルコマンドで書いた方が楽な処理に出くわしたときは、ぜひsubprocessを活用してみてください⚙️✨








































コメント