17.1. subprocess --- サブプロセス管理

バージョン 2.4 で追加.

subprocess モジュールは新しいプロセスの開始、入力/出力/エラーパイプの接続、リターンコードの取得を可能とします。このモジュールはいくつかの古いモジュールや関数を置き換えることを意図しています:

os.system
os.spawn*
os.popen*
popen2.*
commands.*

これらの古いモジュールや関数の代わりに、 このモジュールをどのように使うかについては 古い関数を subprocess モジュールで置き換える で説明します。

参考

POSIX (Linux, BSD など) ユーザは Python 2.7 にバンドルされているバージョンよりも遥かに新しい subprocess32 モジュールをインストールして使うことを強くお勧めします。これは多くの状況においてより良い振る舞いをする差し替えです。

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

17.1.1. subprocess モジュールを使う

サブプロセスを起動するのにお奨めなのは、以下の簡易関数を使うことです。それで満足できないような高度なユースケースがあるなら、背後にある Popen インターフェイスを直接使ってください。

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

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

ここでは引数は よく使われる引数 で説明している一番良く使うものだけ示しています (ですのでシグニチャは省略して少々変わった書き方をしています)。完全な関数シグネチャは Popen コンストラクタと同じです。この関数は引数を直接そのインターフェースへ渡します。

例:

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

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

警告

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

注釈

この関数では stderr=PIPE および stderr=PIPE を使用しないでください。子プロセスが生成する出力の大きさによってはデッドロックしうるからです。パイプが必要なのであれば Popencommunicate() メソッドを使ってください。

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

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

ここでは引数は よく使われる引数 で説明している一番良く使うものだけ示しています (ですのでシグニチャは省略して少々変わった書き方をしています)。完全な関数シグネチャは Popen コンストラクタと同じです。この関数は引数を直接そのインターフェースへ渡します。

例:

>>> 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

バージョン 2.5 で追加.

警告

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

注釈

この関数では stderr=PIPE および stderr=PIPE を使用しないでください。子プロセスが生成する出力の大きさによってはデッドロックしうるからです。パイプが必要なのであれば Popencommunicate() メソッドを使ってください。

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

引数でコマンドを実行し、その出力をバイト文字列として返します。

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

ここでは引数は よく使われる引数 で説明している一番良く使うものだけ示しています (ですのでシグニチャは省略して少々変わった書き方をしています)。完全な関数シグネチャは Popen コンストラクタとほぼ同じで、 stdout だけはこの関数が内部利用で使うので指定は許されません。その他の引数は Popen コンストラクタにそのまま渡されます。

例:

>>> subprocess.check_output(["echo", "Hello World!"])
'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

標準エラーも結果に含めるには、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'

バージョン 2.7 で追加.

警告

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

注釈

この関数では stderr=PIPE を使用しないでください。子プロセスが生成するエラー出力の大きさによってはデッドロックしうるからです。標準エラー出力のパイプが必要なのであれば Popencommunicate() メソッドを使ってください。

subprocess.PIPE

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

subprocess.STDOUT

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

exception subprocess.CalledProcessError

check_call() または check_output() によって実行されるプロセスが非ゼロの終了ステータスを返す場合に送出される例外です。

returncode

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

cmd

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

output

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

17.1.1.1. よく使われる引数

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

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

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

stdoutstdout がパイプで universal_newlinesTrue の場合 open() 関数への 'U' モードとして説明されている universal newlines モードで動作し、全ての行終端コードが '\n' に変換されます。

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

警告

信頼されていないソースからのサニタイズされていない入力を組み込んだシェルコマンドを実行すると、任意のコマンドを実行されることになるセキュリティ上の重大な欠陥 シェルインジェクション(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 を使用する場合、シェルコマンドを構築するために使用される文字列中の空白とシェルのメタ文字を適切にエスケープするために pipes.quote() を使用することができます。

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

17.1.1.2. Popen コンストラクタ

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

class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

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

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

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

注釈

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

>>> import shlex, subprocess
>>> command_line = raw_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 は、もしこれが与えられた場合、ビルトインの open() 関数の該当する引数と同じ意味をもちます: 0 はバッファされないことを意味し、 1 は行ごとにバッファされることを、それ以外の正の値は (ほぼ) その大きさのバッファが使われることを意味します。負の bufsize はシステムのデフォルト値が使われることを意味し、通常これはバッファがすべて有効となります。 bufsize のデフォルト値は 0 (バッファされない) です。

注釈

パフォーマンス上の問題がある場合、 bufsize を -1 か十分大きな正の値 (例えば 4096) に設定し、バッファを有効にすることを勧めます。

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

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

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

close_fds が true の場合、子プロセスが実行される前に 0, 1, 2 以外のすべてのファイルデスクリプタが閉じられます (Unixのみ)。 Windows では close_fds が true の場合、すべてのファイルハンドルは子プロセスに引き継がれません。 Windows の場合、 close_fds を true にしながら、 stdin, stdout, stderr を利用して標準ハンドルをリダイレクトすることはできません。

cwdNone 以外の場合、子プロセスのカレントディレクトリが実行される前に cwd に変更されます。このディレクトリは実行ファイルを探す段階では考慮されませんので、プログラムのパスを cwd に対する相対パスで指定することはできない、ということに注意してください。

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

注釈

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

universal_newlinesTrue にすると、ファイルオブジェクト stdout, stderruniversal newlines モードのテキストファイルとして開きます。行は Unix 慣習の '\r\n' 、古い Macintosh 慣習の '\r' 、 Windows 慣習の '\r\n' のいずれでも終端するでしょうが、どの外部化表現であれ Python プログラムからは '\n' に見えるようになります。

注釈

この機能は Python に universal newline がサポートされている場合 (デフォルト) にのみ有効です。また、 stdout, stdin および stderr のファイルオブジェクトの newlines 属性は communicate() メソッドでは更新されません。

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

17.1.1.3. 例外

子プロセス内で送出された例外は、新しいプログラムの実行開始の前に親プロセスで再送出されます。さらに、この例外オブジェクトには child_traceback という属性が追加されています。この属性は子プロセスの視点からの traceback 情報が格納された文字列です。

最も一般的に起こる例外は OSError です。これは、たとえば存在しないファイルを実行しようとしたときなどに発生します。アプリケーションは OSError 例外に備えておかなければなりません。

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

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

17.1.1.4. セキュリティ

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

17.1.2. Popen オブジェクト

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

Popen.poll()

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

Popen.wait()

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

警告

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

Popen.communicate(input=None)

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

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

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

注釈

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

Popen.send_signal(signal)

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

注釈

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

バージョン 2.6 で追加.

Popen.terminate()

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

バージョン 2.6 で追加.

Popen.kill()

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

バージョン 2.6 で追加.

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

警告

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

Popen.stdin

stdin 引数が PIPE の場合、この属性には子プロセスの入力に使われるファイルオブジェクトになります。そうでない場合は None です。

Popen.stdout

stdout 引数が PIPE の場合、この属性には子プロセスの出力に使われるファイルオブジェクトになります。そうでない場合は None です。

Popen.stderr

stderr 引数が PIPE の場合、この属性には子プロセスのエラー出力に使われるファイルオブジェクトになります。そうでない場合は None です。

Popen.pid

子プロセスのプロセス ID が入ります。

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

Popen.returncode

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

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

17.1.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.1.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.1.4. 古い関数を subprocess モジュールで置き換える

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

注釈

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

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

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

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

output=`mycmd myarg`

これは以下のようになります:

output = check_output(["mycmd", "myarg"])

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

output=`dmesg | grep hda`

これは以下のようになります:

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`

これは以下のようになります:

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

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

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

注釈:

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

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

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

17.1.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.1.4.5. os.popen(), os.popen2(), os.popen3() を置き換える

pipe = os.popen("cmd", 'r', bufsize)
==>
pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout
pipe = os.popen("cmd", 'w', bufsize)
==>
pipe = Popen("cmd", shell=True, bufsize=bufsize, stdin=PIPE).stdin
(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)

Unix では、 os.popen2、os.popen3、os.popen4 は実行するコマンドとしてシーケンスも受け入れます。どちらにせよ、引数はシェルの干渉を受けることなく直接渡されます。この使い方は以下のように置き換えられます。

(child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode,
                                        bufsize)
==>
p = Popen(["/bin/ls", "-l"], bufsize=bufsize, stdin=PIPE, stdout=PIPE)
(child_stdin, child_stdout) = (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", shell=True, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print "There were some errors"

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

(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)

Unix では、 popen2 は実行するコマンドとしてシーケンスも受け入れます。どちらにせよ、引数はシェルの干渉を受けることなく、直接渡されます。この使い方は、以下のように置き換えられます。

(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 はデフォルトですべてのファイル記述子を閉じますが、 Popen では明示的に close_fds=True を指定する必要があります。

17.1.5. 注釈

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

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

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

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

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

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

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