17.5. subprocess — サブプロセス管理

The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:

os.system
os.spawn*

これらのモジュールや関数の代わりに、 subprocess モジュールをどのように使うかについては以下の節で説明します。

参考

PEP 324 – subprocess モジュールを提案している PEP

17.5.1. subprocess モジュールを使う

サブプロセスを起動するとき、以下の便利関数で十分な場合は、それを使うことが推奨されます。より高度な使い方をするために、根底の Popen インターフェスを直接使うことができます。

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

args で指定された引数でコマンドを実行します。コマンドの完了を待って、 returncode を返します。

上記の引数は、単に よく使われる引数 で記述されている最も一般的な引数です (したがって省略されたシグネチャの中でキーワードのみの記法が使用されています)。完全な関数シグネチャは Popen コンストラクタとほとんど同じです。この関数は、 timeout 以外の引数を直接そのインターフェースへ渡します。

timeout 引数は Popen.wait() に渡されます。タイムアウトが過ぎると子プロセスは kill され、再び wait されます。子プロセスが終了した後で、 TimeoutExpired 例外が改めて送出されます。

例:

>>> subprocess.call(["ls", "-l"])
0

>>> subprocess.call("exit 1", shell=True)
1

警告

システムシェルを shell=True で起動することは、信頼されていない入力と組み合わせるとセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。

注釈

この関数を使用する際は stderr=PIPE および stderr=PIPE を使用しないでください。生成されたパイプが現在のプロセスから読み取られないため、子プロセスがOSのパイプバッファを埋めてしまうほどの出力データを生成した場合、子プロセスがブロックされることがあります。

バージョン 3.3 で変更: timeout が追加されました。

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

指定された引数でコマンドを実行し、完了を待ちます。コマンドのリターンコードがゼロならば関数は処理を返しますが、そうでなければ CalledProcessError 例外を送出します。 CalledProcessError オブジェクトにはリターンコードが returncode 属性として収められています。

上記の引数は、単に よく使われる引数 で記述されている最も一般的な引数です (したがって省略されたシグネチャの中でキーワードのみの記法が使用されています)。完全な関数シグネチャは Popen コンストラクタとほとんど同じです。この関数は、 timeout 以外の引数を直接そのインターフェースへ渡します。

timeout 引数は Popen.wait() に渡されます。タイムアウトが過ぎると子プロセスは kill され、再び wait されます。子プロセスが終了した後で、 TimeoutExpired 例外が改めて送出されます。

例:

>>> subprocess.check_call(["ls", "-l"])
0

>>> subprocess.check_call("exit 1", shell=True)
Traceback (most recent call last):
   ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

警告

システムシェルを shell=True で起動することは、信頼されていない入力と組み合わせるとセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。

注釈

この関数を使用する際は stderr=PIPE および stderr=PIPE を使用しないでください。生成されたパイプが現在のプロセスから読み取られないため、子プロセスがOSのパイプバッファを埋めてしまうほどの出力データを生成した場合、子プロセスがブロックされることがあります。

バージョン 3.3 で変更: timeout が追加されました。

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)

引数でコマンドを実行し、その出力を返します。

コマンドのリターンコードが非ゼロならば CalledProcessError 例外を送出します。 CalledProcessError オブジェクトには、リターンコードが returncode 属性に、コマンドからの出力が output 属性に、それぞれ収められています。

上記の引数は、単に よく使われる引数 で記述されている最も一般的な引数です (したがって省略されたシグネチャの中でキーワードのみの記法が使用されています)。完全な関数シグネチャは Popen コンストラクタとほとんど同じです。この関数は、 timeout 以外の引数を直接そのインターフェースへ渡します。加えて、 stdout はサブプロセスから出力を集めるために内部で使用されるので、引数としては使用できません。

timeout 引数は Popen.wait() に渡されます。タイムアウトが過ぎると子プロセスは kill され、再び wait されます。子プロセスが終了した後で、 TimeoutExpired 例外が改めて送出されます。

例:

>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'

>>> subprocess.check_output(["echo", "Hello World!"], universal_newlines=True)
'Hello World!\n'

>>> subprocess.check_output("exit 1", shell=True)
Traceback (most recent call last):
   ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

デフォルトで、この関数はデータをエンコードされたバイトとして返します。出力されたデータの実際のエンコーディングは起動されているコマンドに依存するので、テキストへのデコードは通常アプリケーションレベルで扱われる必要があります。

よく使われる引数 で記述されているように、この振る舞いは universal_newlinesTrue にセットすることでオーバーライドできます。

標準エラーも結果に含めるには、 stderr=subprocess.STDOUT を使います:

>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directory\n'

バージョン 3.1 で追加.

警告

システムシェルを shell=True で起動することは、信頼されていない入力と組み合わせるとセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。

注釈

この関数を使用する際は stderr=PIPE を使用しないでください。生成されたパイプが現在のプロセスから読み取られないため、子プロセスがOSのパイプバッファを埋めてしまうほどの出力データを生成した場合、子プロセスがブロックされることがあります。

バージョン 3.3 で変更: timeout が追加されました。

subprocess.DEVNULL

Popenstdin, stdout, stderr 引数に渡して、 標準入出力を os.devnull から入出力するように指定するための特別な値。

バージョン 3.3 で追加.

subprocess.PIPE

Popenstdin, stdout, stderr 引数に渡して、標準ストリームに対するパイプを開くことを指定するための特別な値.

subprocess.STDOUT

Popenstderr 引数に渡して、標準エラーが標準出力と同じハンドルに出力されるように指定するための特別な値.

exception subprocess.SubprocessError

このモジュールの他のすべての例外のための基底クラス。

バージョン 3.3 で追加.

exception subprocess.TimeoutExpired

SubprocessError のサブクラス。子プロセスを wait している間にタイムアウトが過ぎた場合に送出されます。

cmd

子プロセスを spawn するために使用されるコマンド。

timeout

タイムアウト秒数。

output

この例外が check_output() によって送出された場合は子プロセスの出力。そうでなければ None です。

バージョン 3.3 で追加.

exception subprocess.CalledProcessError

SubprocessError のサブクラス。 check_call() または check_output() によって実行される プロセスが非 0 の終了ステータスを返す場合に送出されます。

returncode

子プロセスの終了ステータス。

cmd

子プロセスを spawn するために使用されるコマンド。

output

この例外が check_output() によって送出された場合は子プロセスの出力。そうでなければ None です。

17.5.1.1. よく使われる引数

幅広いユースケースをサポートするために、 Popen コンストラクタ (とその他の便利関数) は、多くのオプション引数を受け付けます。典型的なユースケースについては、これらの引数の多くはデフォルト値のままで問題ありません。一般的に必要とされる引数は以下の通りです:

args はすべての呼び出しに必要で、文字列あるいはプログラム引数のシーケンスでなければなりません。一般に、引数のシーケンスを渡す方が望ましいです。なぜなら、モジュールが必要な引数のエスケープやクオート (例えばファイル名中のスペースを許すこと) の面倒を見ることができるためです。単一の文字列を渡す場合、 shellTrue でなければなりません (以下を参照)。もしくは、その文字列は引数を指定せずに実行される単なるプログラムの名前でなければなりません。

stdin, stdout および stderr には、実行するプログラムの標準入力、標準出力、および標準エラー出力の ファイルハンドルをそれぞれ指定します。とりうる値は PIPE, DEVNULL, 既存のファイルデスクリプタ (正の整数)、既存のファイルオブジェクト、そして None です。 PIPE を指定すると新しいパイプが子プロセスに向けて作られます。 DEVNULL を指定すると特殊ファイル os.devnull が使用されます。デフォルト設定の None を指定するとリダイレクトは起こりません。子プロセスのファイルハンドルはすべて親から受け継がれます。 加えて、 stderrSTDOUT にすると、子プロセスの stderr からの出力は stdout と同じファイルハンドルに出力されます。

If universal_newlines is False the file objects stdin, stdout and stderr will be opened as binary streams, and no line ending conversion is done.

universal_newlinesTrue の場合、これらのファイルオブジェクトは locale.getpreferredencoding(False) によって返されたエンコーディングを使用して universal newlines モードでテキストストリームとして開かれます。 stdin については、入力での行末文字 '\n' はデフォルトの行セパレータ os.linesep に変換されます。 stdoutstderr については、出力での行末はすべて '\n' に変換されます。詳細は io.TextIOWrapper クラスのドキュメンテーションでコンストラクタの newline 引数が None である場合を参照してください。

注釈

The newlines attribute of the file objects Popen.stdin, Popen.stdout and Popen.stderr are not updated by the Popen.communicate() method.

shellTrue なら、指定されたコマンドはシェルによって実行されます。あなたが Python を主として (ほとんどのシステムシェル以上の) 強化された制御フローのために使用していて、さらにシェルパイプ、ファイル名ワイルドカード、環境変数展開、~ のユーザホームディレクトリへの展開のような他のシェル機能への簡単なアクセスを望むなら、これは有用かもしれません。しかしながら、 Python 自身が多くのシェル的な機能の実装を提供していることに注意してください (特に glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser(), shutil)。

バージョン 3.3 で変更: universal_newlinesTrue の場合、クラスはエンコーディング locale.getpreferredencoding() の代わりに locale.getpreferredencoding(False) を使用します。この変更についての詳細は、 io.TextIOWrapper クラスを参照してください。

警告

信頼されていないソースからのサニタイズされていない入力を組み込んだシェルコマンドを実行すると、任意のコマンドを実行されることになるセキュリティ上の重大な欠陥 シェルインジェクション(en) に対して脆弱になります。この理由から、コマンド文字列が外部入力から構成される場合、 shell=True絶対に使うべきではありません:

>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

shell=False はシェルに基づくすべての機能を無効にしますが、この脆弱性の影響を受けません; shell=False を動かすのに役立つヒントについては Popen コンストラクタのドキュメント中の注釈を参照してください。

shell=True を使用する場合、シェルコマンドを構築するために使用される文字列中の空白とシェルのメタ文字を適切にエスケープするために shlex.quote() を使用することができます。

これらのオプションは、他のすべてのオプションとともに Popen コンストラクタのドキュメンテーションの中で、より詳細に説明されています。

17.5.1.2. Popen コンストラクタ

このモジュールの中で、根底のプロセス生成と管理は Popen クラスによって扱われます。簡易関数によってカバーされないあまり一般的でないケースを開発者が扱えるように、 Popen クラスは多くの柔軟性を提供しています。

class 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=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())

新しいプロセスで子のプログラムを実行します。Unix においては、子のプログラムを実行するために、このクラスは os.execvp() のような振る舞いを使用します。 Windows においては、このクラスは Windows の CreateProcess() 関数を使用します。 Popen への引数は以下の通りです。

args はプログラム引数のシーケンスか、単一の文字列でなければなりません。デフォルトでは、 args がシーケンスの場合に実行されるプログラムは args の最初の要素です。 args が文字列の場合、解釈はプラットフォーム依存であり、下記に説明されます。デフォルトの振る舞いからの追加の違いに関して shell および executable 引数を参照してください。特に明記されない限り、 args をシーケンスとして渡すことが推奨されます。

Unix 上では、 args が文字列の場合、その文字列は実行すべきプログラムの名前またはパスとして解釈されます。しかし、これはプログラムに引数を渡さない場合にのみ可能です。

注釈

args を正しくトークン化するには、 shlex.split() が便利です。このメソッドは特に複雑な状況で活躍します:

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

シェルの中でスペースで区切られたオプション (-input など) と引数 (eggs.txt など) はリストの別の要素として区切られていること、シェルの中で (上にあるようなスペースを含むファイル名や echo コマンドのように) クォーティングかバックスラッシュエスケープが必要なものは単一のリスト要素にされていることに注目してください。

Windows 上では、 args がシーケンスなら Windows における引数シーケンスから文字列への変換 に記述された方法で文字列に変換されます。これは根底の CreateProcess() が文字列上で動作するからです。

shell 引数 (デフォルトでは False) は、実行するプログラムとしてシェルを使用するかどうかを指定します。 shellTrue の場合、 args をシーケンスとしてではなく文字列として渡すことが推奨されます。

Unix で shell=True の場合、シェルのデフォルトは /bin/sh になります。 args が文字列の場合、この文字列はシェルを介して実行されるコマンドを指定します。したがって、文字列は厳密にシェルプロンプトで打つ形式と一致しなければなりません。例えば、文字列の中にスペースを含むファイル名がある場合は、クォーティングかバックスラッシュエスケープが必要です。 args がシーケンスの場合には、最初の要素はコマンド名を表わす文字列として、残りの要素は追加の引数としてシェルに渡されます。つまり、以下の Popen と等価ということです:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

Windows で shell=True とすると、 COMSPEC 環境変数がデフォルトシェルを指定します。 Windows で shell=True を指定する必要があるのは、実行したいコマンドがシェルに組み込みの場合だけです (例えば dircopy)。バッチファイルやコンソールベースの実行ファイルを実行するために shell=True は必要ありません。

警告

shell=True を渡すことは、信頼されていない入力と組み合わせるとセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。

bufsize will be supplied as the corresponding argument to the open() function when creating the stdin/stdout/stderr pipe file objects: 0 means unbuffered (read and write are one system call and can return short), 1 means line buffered, any other positive value means use a buffer of approximately that size. A negative bufsize (the default) means the system default of io.DEFAULT_BUFFER_SIZE will be used.

バージョン 3.3.1 で変更: bufsize now defaults to -1 to enable buffering by default to match the behavior that most code expects. In versions prior to Python 3.2.4 and 3.3.1 it incorrectly defaulted to 0 which was unbuffered and allowed short reads. This was unintentional and did not match the behavior of Python 2 as most code expected.

executable 引数は、実行される置換プログラムを指定します。これが必要になるのは極めて稀です。 shell=False のときは、 executableargs で指定されている実行プログラムを置換します。しかし、オリジナルの args は依然としてプログラムに渡されます。ほとんどのプログラムは、 args で指定されたプログラムをコマンド名として扱います。そして、それは実際に実行されたプログラムとは異なる可能性があります。 Unix において、 ps のようなユーティリティの中では、 args 名が実行ファイルの表示名になります。 shell=True の場合、 Unix において executable 引数はデフォルトの /bin/sh に対する置換シェルを指定します。

stdin, stdout および stderr には、実行するプログラムの標準入力、標準出力、および標準エラー出力の ファイルハンドルをそれぞれ指定します。とりうる値は PIPE, DEVNULL, 既存のファイルデスクリプタ (正の整数)、既存のファイルオブジェクト、そして None です。 PIPE を指定すると新しいパイプが子プロセスに向けて作られます。 DEVNULL を指定すると特殊ファイル os.devnull が使用されます。デフォルト設定の None を指定するとリダイレクトは起こりません。子プロセスのファイルハンドルはすべて親から受け継がれます。 加えて、 stderrSTDOUT にすると、子プロセスの stderr からの出力は stdout と同じファイルハンドルに出力されます。

preexec_fn に callable オブジェクトが指定されている場合、このオブジェクトは子プロセスが起動されてから、プログラムが exec される直前に呼ばれます。(Unixのみ)

警告

アプリケーションの中に複数のスレッドが存在する状態で preexec_fn パラメータを使用するのは安全ではありません。 exec が呼ばれる前に、子プロセスがデッドロックすることがあります。それを使用しなければならない場合、プログラムを自明なものにしておいてください! 呼び出すライブラリの数を最小にしてください。

注釈

子プロセスのために環境を修正する必要がある場合、 preexec_fn の中でそれをするのではなく env パラメータを使用します。 start_new_session パラメータは、子プロセスの中で os.setsid() を呼ぶ過去の一般的な preexec_fn の使用方法の代わりになります。

close_fds が true の場合、子プロセスが実行される前に 0, 1, 2 以外のすべてのファイルデスクリプタが閉じられます (Unixのみ)。デフォルトはプラットフォームによって異なります: Unix では常に true です。 Windows では stdin/stdout/stderrNone のときに true で、そうでなければ false です。 Windows で close_fds が true の場合、すべてのファイルハンドルは子プロセスに引き継がれません。 Windows の場合、 close_fds を true にしながら、 stdin, stdout, stderr を利用して標準ハンドルをリダイレクトすることはできません。

バージョン 3.2 で変更: close_fds のデフォルトは、 False から上記のものに変更されました。

pass_fds はオプションで、親と子の間で開いたままにしておくファイルデスクリプタのシーケンスを指定します。何らかの pass_fds を渡した場合、 close_fds は強制的に True になります。 (Unixのみ)

バージョン 3.2 で追加: pass_fds パラメータが追加されました。

cwdNone でない場合、この関数は子を実行する前に作業ディレクトリを cwd に変更します。特に、実行ファイルのパスが相対パスの場合、この関数は、 executable (あるいは args の中の最初の要素) を cwd からの相対で検索します。

If restore_signals is true (the default) all signals that Python has set to SIG_IGN are restored to SIG_DFL in the child process before the exec. Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals. (Unix only)

バージョン 3.2 で変更: restore_signals が追加されました。

If start_new_session is true the setsid() system call will be made in the child process prior to the execution of the subprocess. (Unix only)

バージョン 3.2 で変更: start_new_session が追加されました。

envNone 以外の場合、これは新しいプロセスでの環境変数を定義します。デフォルトでは、子プロセスは現在のプロセスの環境変数を引き継ぎます。

注釈

env を特定の値として与える場合、プログラムを実行するのに必要な変数全てを与えなければなりません。 Windows で side-by-side assembly を実行するためには、 env は正しい SystemRoot含まなければいけません

universal_newlinesTrue の場合、 よく使われる引数 で記述されているように、ファイルオブジェクト stdin, stdout, stderr は universal newlines モードでテキストストリームとして開かれます。そうでなければバイナリストリームとして開かれます。

startupinfo は、根底の CreateProcess 関数に渡される STARTUPINFO オブジェクトになります。 creationflags は、与えられるなら、 CREATE_NEW_CONSOLE または CREATE_NEW_PROCESS_GROUP にできます。(Windows のみ)

Popen オブジェクトは with 文によってコンテキストマネージャとしてサポートされます: 終了時には標準ファイルディスクリプタが閉じられ、プロセスは wait されます。

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

バージョン 3.2 で変更: コンテキストマネージャサポートが追加されました。

17.5.1.3. 例外

子プロセス内で raise した例外は、新しいプログラムが実行される前であれば、親プロセスでも raise されます。さらに、この例外オブジェクトには child_traceback という属性が追加されており、これには子プロセスの視点からの traceback 情報が格納されています。

もっとも一般的に起こる例外は OSError です。これは、たとえば存在しないファイルを実行しようとしたときなどに発生します。アプリケーションは OSError 例外にはあらかじめ準備しておく必要があります。

不正な引数で Popen が呼ばれた場合は、 ValueError が発生します。

check_call() および check_output() はもし呼び出されたプロセスがゼロでないリターンコードを返したならば CalledProcessError を送出します。

call()Popen.communicate() のような timeout パラメーターを受け取るすべての関数とメソッドは、プロセスが終了する前にタイムアウトが過ぎた場合に TimeoutExpired を送出します。

このモジュールで定義された例外はすべて SubprocessError から継承します。

バージョン 3.3 で追加: SubprocessError 基底クラスが追加されました。

17.5.1.4. セキュリティ

ほかの popen 関数とは異なり、この実装は決して暗黙のうちにシステムシェルを実行しません。これはシェルのメタ文字を含むすべての文字が子プロセスに安全に渡されるということを意味しています。明らかに、シェルが明示的に起動される場合は、空白とメタキャラクターがすべて適切にクオートされていることを保証するのはアプリケーションの責任です。

17.5.2. Popen オブジェクト

Popen クラスのインスタンスには、以下のようなメソッドがあります:

Popen.poll()

子プロセスが終了しているかどうかを検査します。 returncode 属性を設定し、返します。

Popen.wait(timeout=None)

子プロセスが終了するまで待ちます。 returncode 属性を設定し、返します。

プロセスが timeout 秒の後に終了しない場合、 TimeoutExpired 例外を送出します。この例外を捕捉して、 wait を再実行することは安全です。

警告

これは、子プロセスが十分な出力を生成したのに、出力先が、 OS パイプバッファがそれ以上のデータを受け付けるのを待っているような場合に、デッドロックになります。これを避けるために、 communicate() を利用してください。

バージョン 3.3 で変更: timeout が追加されました。

Popen.communicate(input=None, timeout=None)

プロセスと通信します: end-of-file に到達するまでデータを stdin に送信し、 stdout および stderr からデータを受信します。 プロセスが終了するまで待ちます。オプション引数 input には、子プロセスに送られるデータか、あるいはデータを送らない場合は None を指定します。 input の型はバイトか、あるいは universal_newlinesTrue の場合は文字列でなければなりません。

communicate() はタプル (stdoutdata, stderrdata) を返します。

子プロセスの標準入力にデータを送りたい場合は、 Popen オブジェクトを stdin=PIPE と指定して作成しなければなりません。同じく、戻り値のタプルから None ではない値を取得するためには、 stdout=PIPE かつ/または stderr=PIPE を指定しなければなりません。

プロセスが timeout 秒の後に終了しない場合、 TimeoutExpired 例外が送出されます。この例外を捕捉して通信を再実行してもデータは失われません。

タイムアウトが過ぎた場合、子プロセスは kill されません。したがって、適切にクリーンアップを行うために、 行儀のよいアプリケーションは子プロセスを kill してコミュニケーションを終了すべきです:

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

注釈

受信したデータはメモリ中にバッファされます。そのため、返されるデータが大きいかあるいは制限がないような場合はこのメソッドを使うべきではありません。

バージョン 3.3 で変更: timeout が追加されました。

Popen.send_signal(signal)

signal シグナルを子プロセスに送ります。

注釈

Windows では、 SIGTERM は terminate() のエイリアスです。 CTRL_C_EVENT と CTRL_BREAK_EVENT を、 CREATE_NEW_PROCESS_GROUP を含む creationflags で始まった、プロセスに送れます。

Popen.terminate()

子プロセスを止めます。 Posix OSでは、このメソッドは SIGTERM シグナルを子プロセスに送ります。 Windows では、 Win32 API の TerminateProcess() 関数を利用して子プロセスを止めます。

Popen.kill()

子プロセスを kill します。 Posix OS では SIGKILL シグナルを子プロセスに送ります。 Windows では、 kill()terminate() のエイリアスです。

以下の属性も利用可能です:

警告

.stdin.write, .stdout.read, .stderr.read を利用すると、別のパイプのOSパイプバッファがいっぱいになってデッドロックする恐れがあります。これを避けるためには communicate() を利用してください。

Popen.args

The args argument as it was passed to Popen – a sequence of program arguments or else a single string.

バージョン 3.3 で追加.

Popen.stdin

If the stdin argument was PIPE, this attribute is a writeable stream object as returned by open(). If the universal_newlines argument was True, the stream is a text stream, otherwise it is a byte stream. If the stdin argument was not PIPE, this attribute is None.

Popen.stdout

If the stdout argument was PIPE, this attribute is a readable stream object as returned by open(). Reading from the stream provides output from the child process. If the universal_newlines argument was True, the stream is a text stream, otherwise it is a byte stream. If the stdout argument was not PIPE, this attribute is None.

Popen.stderr

If the stderr argument was PIPE, this attribute is a readable stream object as returned by open(). Reading from the stream provides error output from the child process. If the universal_newlines argument was True, the stream is a text stream, otherwise it is a byte stream. If the stderr argument was not PIPE, this attribute is None.

Popen.pid

子プロセスのプロセス番号です。

shell 引数を True にセットした場合は、生成されたシェルのプロセス ID になります。

Popen.returncode

poll()wait() (か、間接的に communicate())から設定された、子プロセスの終了ステータスが入ります。 None はまだその子プロセスが終了していないことを示します。

負の値 -N は子プロセスがシグナル N により中止させられたことを示します (Unix のみ)。

17.5.3. Windows Popen ヘルパ

STARTUPINFO クラスと以下の定数は、Windows でいつでも利用できます。

class subprocess.STARTUPINFO

Popen の生成に使われる Windows STARTUPINFO 構造の部分的なサポートです。

dwFlags

特定の STARTUPINFO の属性が、プロセスがウィンドウを生成するときに使われるかを決定するビットフィールドです:

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
hStdInput

dwFlagsSTARTF_USESTDHANDLES を指定すれば、この属性がプロセスの標準入力処理です。 STARTF_USESTDHANDLES が指定されなければ、標準入力のデフォルトはキーボードバッファです。

hStdOutput

dwFlagsSTARTF_USESTDHANDLES を指定すれば、この属性がプロセスの標準出力処理です。そうでなければ、この属性は無視され、標準出力のデフォルトはコンソールウィンドウのバッファです。

hStdError

dwFlagsSTARTF_USESTDHANDLES を指定すれば、この属性がプロセスの標準エラー処理です。そうでなければ、この属性は無視され、標準エラーのデフォルトはコンソールウィンドウのバッファです。

wShowWindow

dwFlagsSTARTF_USESHOWWINDOW を指定すれば、この属性は ShowWindow 関数の nCmdShow パラメタで指定された値なら、 SW_SHOWDEFAULT 以外の任意のものにできます。しかし、この属性は無視されます。

この属性には SW_HIDE が提供されています。これは、 Popenshell=True として呼び出されたときに使われます。

17.5.3.1. 定数

subprocess モジュールは、以下の定数を公開します。

subprocess.STD_INPUT_HANDLE

標準入力デバイスです。この初期値は、コンソール入力バッファ、 CONIN$ です。

subprocess.STD_OUTPUT_HANDLE

標準出力デバイスです。この初期値は、アクティブコンソールスクリーン、 CONOUT$ です。

subprocess.STD_ERROR_HANDLE

標準エラーデバイスです。この初期値は、アクティブコンソールスクリーン、 CONOUT$ です。

subprocess.SW_HIDE

ウィンドウを隠します。別のウィンドウが活性化します。

subprocess.STARTF_USESTDHANDLES

追加情報を保持する、 STARTUPINFO.hStdInput, STARTUPINFO.hStdOutput, および STARTUPINFO.hStdError 属性を指定します。

subprocess.STARTF_USESHOWWINDOW

追加情報を保持する、 STARTUPINFO.wShowWindow 属性を指定します。

subprocess.CREATE_NEW_CONSOLE

新しいプロセスが、親プロセスのコンソールを継承する (デフォルト) のではなく、新しいコンソールを持ちます。

Popenshell=True として生成されたとき、このフラグは必ず設定されます。

subprocess.CREATE_NEW_PROCESS_GROUP

新しいプロセスグループが生成されることを指定する Popen creationflags パラメタです。このフラグは、サブプロセスで os.kill() を使うのに必要です。

CREATE_NEW_CONSOLE が指定されていたら、このフラグは無視されます。

17.5.4. 古い関数を subprocess モジュールで置き換える

以下、この節では、”a が b になる” と書かれているものは a の代替として b が使えるということを表します。

注釈

この節で紹介されている “a” 関数はすべて、実行するプログラムが見つからないときは (概ね) 静かに終了します。それに対して “b” 代替手段は OSError 例外を発生させます。

また、要求された操作が非 0 の終了コードを返した場合、 check_output() を使用した置き換えは CalledProcessError で失敗します。その出力は、送出された例外の output 属性として利用可能です。

以下の例では、適切な関数が subprocess モジュールからすでにインポートされていることを前提としています。

17.5.4.1. /bin/sh シェルのバッククォートを置き換える

output=`mycmd myarg`
# becomes
output = check_output(["mycmd", "myarg"])

17.5.4.2. シェルのパイプラインを置き換える

output=`dmesg | grep hda`
# becomes
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

p2 を開始した後の p1.stdout.close() の呼び出しは、p1 が p2 の前に存在した場合に、p1 が SIGPIPE を受け取るために重要です。

あるいは、信頼された入力に対しては、シェル自身のパイプラインサポートを直接使用することもできます:

output=`dmesg | grep hda`
# becomes
output=check_output("dmesg | grep hda", shell=True)

17.5.4.3. os.system() を置き換える

sts = os.system("mycmd" + " myarg")
# becomes
sts = call("mycmd" + " myarg", shell=True)

ノート:

  • このプログラムは普通シェル経由で呼び出す必要はありません。

より現実的な例ではこうなるでしょう:

try:
    retcode = call("mycmd" + " myarg", shell=True)
    if retcode < 0:
        print("Child was terminated by signal", -retcode, file=sys.stderr)
    else:
        print("Child returned", retcode, file=sys.stderr)
except OSError as e:
    print("Execution failed:", e, file=sys.stderr)

17.5.4.4. os.spawn 関数群を置き換える

P_NOWAIT の例:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT の例:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

シーケンスを使った例:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

環境変数を使った例:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

17.5.4.5. os.popen(), os.popen2(), os.popen3() を置き換える

(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
(child_stdin,
 child_stdout,
 child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
 child_stdout,
 child_stderr) = (p.stdin, p.stdout, p.stderr)
(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

終了コードハンドリングは以下のように解釈します:

pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
    print("There were some errors")
==>
process = Popen(cmd, 'w', stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print("There were some errors")

17.5.4.6. popen2 モジュールの関数群を置き換える

注釈

popen2 関数の cmd 引数が文字列の場合、コマンドは /bin/sh によって実行されます。リストの場合、コマンドは直接実行されます。

(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen(["somestring"], shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

popen2.Popen3 および popen2.Popen4 は基本的には subprocess.Popen と同様です。ただし、違う点は:

  • Popen は実行できなかった場合に例外を発生させます。

  • capturestderr 引数は stderr 引数に代わりました。

  • stdin=PIPE および stdout=PIPE を指定する必要があります。

  • popen2 はデフォルトですべてのファイルデスクリプタを閉じます。しかし、すべてのプラットフォーム上で、あるいは過去の Python バージョンでこの振る舞いを保証するためには、 Popen に対して close_fds=True を指定しなければなりません。

17.5.5. レガシーのシェル実行関数

このモジュールでは、以下のような 2.x commands モジュールからのレガシー関数も提供しています。これらの操作は、暗黙的にシステムシェルを起動します。また、セキュリティに関して上述した保証や例外処理一貫性は、これらの関数では有効ではありません。

subprocess.getstatusoutput(cmd)

シェル中の cmd を実行して (status, output) を返します。

Execute the string cmd in a shell with Popen and return a 2-tuple (status, output) via Popen.communicate(). Universal newlines mode is used; see the notes on よく使われる引数 for more details.

A trailing newline is stripped from the output. The exit status for the command can be interpreted according to the rules for the C function wait(). Example:

>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> subprocess.getstatusoutput('cat /bin/junk')
(256, 'cat: /bin/junk: No such file or directory')
>>> subprocess.getstatusoutput('/bin/junk')
(256, 'sh: /bin/junk: not found')

Availability: Unix & Windows

バージョン 3.3.4 で変更: Windows support added

subprocess.getoutput(cmd)

シェル中の cmd を実行して出力 (stdout と stderr) を返します。

getstatusoutput() に似ていますが、終了ステータスは無視され、コマンドの出力のみを返します。例えば:

>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'

Availability: Unix & Windows

バージョン 3.3.4 で変更: Windows support added

17.5.6. 注釈

17.5.6.1. Windows における引数シーケンスから文字列への変換

Windows では、 args シーケンスは以下の (MS C ランタイムで使われる規則に対応する) 規則を使って解析できる文字列に変換されます:

  1. 引数は、スペースかタブのどちらかの空白で分けられます。

  2. ダブルクオーテーションマークで囲まれた文字列は、空白が含まれていたとしても 1 つの引数として解釈されます。クオートされた文字列は引数に埋め込めます。

  3. バックスラッシュに続くダブルクオーテーションマークは、文字通りのダブルクオーテーションマークと解釈されます。

  4. バックスラッシュは、ダブルクオーテーションが続かない限り、文字通りに解釈されます。

  5. 複数のバックスラッシュにダブルクオーテーションマークが続くなら、バックスラッシュ 2 つで 1 つのバックスラッシュ文字と解釈されます。バックスラッシュの数が奇数なら、最後のバックスラッシュは規則 3 に従って続くダブルクオーテーションマークをエスケープします。

参考

shlex

コマンドラインを解析したりエスケープしたりする関数を提供するモジュール。