2021年07月30日 更新
どうも、クラゲです。
Pythonプログラム上でLinuxコマンドを実行したいときに役立つsubprocessです。例えば、効果音の音声出力や他のスクリプトを実行させるなどに使えます。
PythonプログラムでLinuxコマンドを実行する方法として os.system がありますが、これは古い方式でそのうち subprocess に置き換えられる可能性があるため、こちらを使います。 https://docs.python.org/ja/3/library/subprocess.html
例えばls
コマンドをPythonプログラムの中で使いたいとします。
Pythonプログラムでは以下のように書きます。
import subprocess
subprocess.run(['ls'])
今度はオプション付のコマンド例です。
-l
を付けて、ls -l
にするとファイルの詳細が表示されます。
Pythonプログラムでは以下のように書きます
import subprocess
subprocess.run(['ls', '-l'])
さらにオプションをついた場合の例です。
-S
を付けて、ls -l -S
にするとファイルサイズの大きい順にソートされます。
Pythonプログラムでは以下のように書きます。
import subprocess
subprocess.run(['ls', '-l', '-S'])
大体分かりましたね?
スペースを区切りとして、リスト化したものを引数に渡せばOKです。
なお、echo "hello jellyfish"
のように、Linuxコマンドの引数にクォーテーションがある場合(別の言い方をするとスペースを含んでいる引数の場合)はクォーテーションは不要となります。
import subprocess
subprocess.run(['echo', 'hello jellyfish'])
先程の subprocess.run
は同期処理です。
「同期処理」とは、処理が終わってから次の処理に進むという意味です。
先程のlsコマンドだと一瞬で処理が終わってしまうため、音声出力を行うコマンド aplay
で試してみましょう。2つの音声ファイル a.wav
と b.wav
を用意して以下を実行します。数秒程度の長さのファイルがいいと思います。
import subprocess
subprocess.run(['aplay', 'a.wav'])
subprocess.run(['aplay', 'b.wav'])
a.wav
の再生が終わってから b.wav
の再生が始まったと思います。
一方で subprocess.Popen を使うと非同期処理が行えます。
「非同期処理」は、処理が終わっているかに関係なく、次の処理に進むという意味です。
import subprocess
subprocess.Popen(['aplay', 'a.wav'])
subprocess.run(['aplay', 'b.wav'])
両方ともほぼ同時に再生されたかと思います。
このように非同期で処理したい箇所は run
ではなく Popen
を使ってください
非同期で実行させたけど、何らかの処理があった場合に止めたい場合があると思います。
ここでは c.wav
という数十秒以上の曲を準備して実行してみてください。
import subprocess
proc = subprocess.Popen(['aplay', 'c.wav'])
input() #入力待ち
proc.kill()
エンターキーが押されると、c.wav
の再生は強制終了したと思います。
このように、subprocess.Popen
の戻り値を取得しておけば、必要なタイミングでkill
関数を使うことで強制終了させることができます。
以上、subprocessでした!