はじめに
pythonからコマンドを実行したいなと調べたところ、subprocessモジュールというのを見つけた。これは、Pythonから外部プロセスを起動し、そのプロセスとのやり取りを行うことができるモジュールらしいので使い方を調べた。
基本の使い方
基本はsubprocess.run()の引数に配列で実行したいコマンドを渡すことが多そう
import subprocess, sys
completedProcess = subprocess.run(['ls', '-la'])
print(res.returncode) #=> 終了コード
print(res.stdout) #=> 標準出力
print(res.stderr) #=> 標準エラー出力
if completedProcess.returncode != 0:
print('ls failed.', file=sys.stderr)
sys.exit(1)
subprocess.run()の戻り値はCompletedProcess。以下CompletedProcessから取得できるもの
プロパティ | 説明 |
---|---|
args | プロセスを起動するときに使用された引数 |
returncode | 子プロセスの終了コード。一般に、終了ステータス 0 はプロセスが正常に終了 |
stdout | 子プロセスから補足された標準出力です。バイト列、もしくは run() でエンコーディングが指定された場合、エラーの場合、text=True が指定された場合は文字列 |
stderr | 子プロセスから補足された標準出力です。バイト列、もしくは run() でエンコーディングが指定された場合、エラーの場合、text=True が指定された場合は文字列 |
check_returncode() | returncode が非ゼロの場合、CalledProcessError が送出される |
shell=True指定
*や|を使用した場合、shell=Trueをつけて文字列で渡すと実行できる
cmd_str = "ps aux | grep python3"
subprocess.run(cmd_str, shell=True)
これは外部からの入力を直接コマンドに組み込むことができるということで、意図しないコマンドの実行やシステムへの悪意あるアクセスが可能にな流ということでもある。
使用時に入力を適切にエスケープまたは検証せずに使用すると、セキュリティ上の脆弱性が発生する可能性があるので注意して使えということらしい。
subprocess.run()はコマンド完了まで待つが、subprocess.Popen()を使用するとバックグラウンド実行などが可能になるっぽい。今回はsubprocess.run()で十分そうなので、必要ならまた調べる
おわりに
シェルコマンドを使えるということは、rm
で自分のディレクトリ消すなんてこともできるわけで、セキュリティには気を使わないと大惨事になる予感はしつつ、強力な機能でもあるので気をつけて活用した
参考