Pythonのsubprocessモジュールの使用 [misc]
先日、Linux 上で Python スクリプトを作成する機会があった。
その際、OS のコマンドの実行に subprocess モジュールのどの関数を使用すべきかを理解するまでに時間を要したため、備忘録としてまとめてみた。
(Python のバージョン: 3.9.2)
1. 使用する関数の判断方法
2. 備考
その際、OS のコマンドの実行に subprocess モジュールのどの関数を使用すべきかを理解するまでに時間を要したため、備忘録としてまとめてみた。
(Python のバージョン: 3.9.2)
1. 使用する関数の判断方法
(1) コマンドの実行結果を実行時に値として取得する場合
subprocess.Popen() を使用する。
【サンプルコード-1】
#!/usr/bin/python import subprocess cmd = 'ls -1 /var/log/clamav' print("# cmd:", cmd) proc = subprocess.Popen(cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print("# proc.stdout:") for i in proc.stdout: print(i, end='') print("# proc.stderr:") for i in proc.stderr: print(i, end='') proc.wait() print("# proc.wait(); proc.returncode:", proc.returncode)
・コマンドの終了を待たず、実行結果を値として取得する。
・Popen.wait() によりコマンドの終了を待つ。
Popen.wait() を Popen.communicate() に変更しても同じ結果が得られる。
・コマンドの終了後に終了ステータスを値として取得する。
(2) 上記以外の場合
(a) subprocess.run() の使用を検討する。
【サンプルコード-2】
#!/usr/bin/python import subprocess cmd = 'which xz' print("# cmd:", cmd) proc = subprocess.run(cmd, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print("# proc.returncode:", proc.returncode) if proc.returncode == 0: print("# proc.stdout:", proc.stdout.rstrip('\n')) else: print("# proc.stderr:", proc.stderr.rstrip('\n'))
・コマンドの終了後に終了ステータスと実行結果を値として取得する。
【サンプルコード-3】
#!/usr/bin/python import subprocess cmd = 'which xz' print("# cmd:", cmd) proc = subprocess.run(cmd, shell=True, text=True) print("# proc.returncode:", proc.returncode)
・終了ステータスのみを値として取得する。
・コマンド実行時の出力の有無は、コマンドのリダイレクトの設定による。
出力なしとする場合には、'cmd >/dev/null 2>&1' のように実行する。
(b) 終了ステータスのみが必要な場合は、subprocess.call() の使用も検討する。
【サンプルコード-4】
#!/usr/bin/python import subprocess cmd = 'which xz >/dev/null 2>&1' print("# cmd:", cmd) status = subprocess.call(cmd, shell=True) print("# status:", status)
・終了ステータスを値として取得する。
・コマンド実行時の出力なし。
コマンド実行時の出力の有無は、コマンドのリダイレクトの設定による。
2. 備考
サンプルコードの実行結果は、下記の通りである。
% ./ex-1.py # cmd: ls -1 /var/log/clamav # proc.stdout: clamav.log clamav.log.1 clamav.log.2.gz clamav.log.3.gz clamav.log.4.gz freshclam.log freshclam.log.1.gz freshclam.log.2.gz freshclam.log.3.gz freshclam.log.4.gz # proc.stderr: # proc.wait(); proc.returncode: 0 % ./ex-2.py # cmd: which xz # proc.returncode: 0 # proc.stdout: /usr/bin/xz % ./ex-3.py # cmd: which xz /usr/bin/xz # proc.returncode: 0 % ./ex-4.py # cmd: which xz >/dev/null 2>&1 # status: 0
コメント 0