最近仕方ないのでPythonを覚えた。その中でよくお世話になるのがこのsubprocess Module。よく分からないならrun Methodを使っとけばいいと書いてあるので素直に毎回そうしてる。しかしお世話になる割にはいまいちよく分からない。大量の引数があるがそれぞれ一体何の意味があるのか。なんか困ったことがあるたびに毎回検索してる気がするので仕方ないから頑張って調べることにした。ちなみに以下はすべて3.7.1を基準に書いてある。
とりあえずReferenceにはこう書いてある。
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
しかし「*」と引数にあるがこれなんだと思ってReferenceをよく読んだらよく使う引数を表記しただけらしい。ということは他にもあるから「*」なのだな。さらに読むと引数はPopenコンストラクタのそれとほぼ一緒。だったらPopenでいいのではないかと思うがまあいいだろう。
args
実行したいコマンド。もう言わずもがな。
input
子プロセスの標準入力に渡される。文字列もしくはバイト列で指定する。stdinと何が違うのかよく分からんが柔軟な指定が出来そうではある。
stdin
stdout
stderr
それぞれ標準入力、標準出力、標準エラー。
capture_output
Trueの場合stdoutとstderrがキャプチャされる。実行結果がCompletedProcess.stdoutとCompletedProcess.stderrにバイト列で返される。内部ではstdout=PIPEとstderr=PIPEが渡されるので普通に
stdout = subprocess.PIPE, stderr = subprocess.STDOUT
とやるのと何も変わらない。表記的にシンプルなcapture_outputを使うのがおそらく正しいのだろう。
shell
shell依存のコマンドを実行するときに使う。滅多に使うことはない。
cwd
子プロセスの作業ディレクトリを指定する。動画関連とか大量のtempを吐くような時に使うんだろう。
timeout
もう名前通りの子プロセスの実行タイムアウト。TimeoutExpired例外を投げる。
check
Trueの場合CompletedProcess.returncodeが0以外だとCalledProcessError例外を返す。Falseだと何事もなく処理が進む。
encoding
標準入出力及びエラーを文字列で返す場合の文字コード。
errors
標準入出力及びエラーを文字列で返す場合のデコードエラー部分を指定文字列で置換する。
text
universal_newlinesのエイリアス。確かにuniversal_newlinesは分かりにくい。
universal_newlines
Trueの場合標準入出力及びエラーに文字列が返る。Falseの場合バイト列が返る。互換性保持のために残してある。textを使う事。
Popenコンストラクタと引数はほぼ一緒というのだからついでに見ていくが8割方理解できない。ほとんどがLinux系の話。
subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)
bufsize
見たまんまバッファサイズ。open()に渡される。0はなし。1は行単位だから当然text=Trueで使う。正の整数は全サイズ。負の整数はシステム依存でこれがデフォルト。
executable
置換プログラムを指定する。滅多に必要ないと書いてあるが確かに使いどころが理解できない。なんかWindowsにはあまり関係ないみたい。
preexec_fn
呼び出し可能なオブジェクトを指定すると子プロセスで呼び出されるとあるが何のことやらさっぱり。デッドロックの可能性があるから取り扱いには注意する事とかenvやstart_new_sessionで代替できるか考えろとか書いてあるのであまり深く考える必要はなさげ。Windowsには関係ない。
close_fds
Trueの場合子プロセスが実行される前に標準入出力及びエラー以外のファイル記述子が閉じられる。
restore_signals
Trueの場合すべてのシグナルは子プロセス実行前にSIG_DFLに戻される。シグナルとは要するにプロセス間のイベントの事。理解できなくても問題なさそう。Windowsには関係ない
creationflags
Windowsのみ。CreateProcess()に渡される。以下のflagをサポートしている。
subprocess.CREATE_NEW_CONSOLE | pythonのコンソールを流用せず新しいコンソールで実行する。 |
subprocess.CREATE_NEW_PROCESS_GROUP | 新しいプロセスグループを生成する。os.kill()を使うのに必要。CREATE_NEW_CONSOLEが指定されていたら無視される。 |
subprocess.ABOVE_NORMAL_PRIORITY_CLASS | 子プロセスの優先度を「通常以上」にする。 |
subprocess.BELOW_NORMAL_PRIORITY_CLASS | 子プロセスの優先度を「通常以下」にする。 |
subprocess.HIGH_PRIORITY_CLASS | 子プロセスの優先度を「高」にする。 |
subprocess.IDLE_PRIORITY_CLASS | 子プロセスの優先度を「低」にする。 |
subprocess.NORMAL_PRIORITY_CLASS | 子プロセスの優先度を「通常」にする。 |
subprocess.REALTIME_PRIORITY_CLASS | 子プロセスの優先度を「リアルタイム」にする。 |
subprocess.CREATE_NO_WINDOW | コンソールなしで実行する。 |
subprocess.DETACHED_PROCESS | 子プロセスに親プロセスのコンソールへのアクセスを許可しない。CREATE_NEW_CONSOLEとの併用は不可。 |
subprocess.CREATE_DEFAULT_ERROR_MODE | 子プロセスに親プロセスのエラーモードを継承させない。 |
subprocess.CREATE_BREAKAWAY_FROM_JOB | 子プロセスをジョブに関連付けない。つまり親プロセスの終了と子プロセスの終了を連動させない。 |
startupinfo
STARTUPINFOオブジェクトを指定する。
#STARTUPINFOオブジェクトを作る si = subprocess.STARTUPINFO() #dwFlagsを指定する si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW #実行する subprocess.run(command, startupinfo=si)