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
を使用しないでください。子プロセスが生成する出力の大きさによってはデッドロックしうるからです。パイプが必要なのであればPopen
のcommunicate()
メソッドを使ってください。
-
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
を使用しないでください。子プロセスが生成する出力の大きさによってはデッドロックしうるからです。パイプが必要なのであればPopen
のcommunicate()
メソッドを使ってください。
-
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
を使用しないでください。子プロセスが生成するエラー出力の大きさによってはデッドロックしうるからです。標準エラー出力のパイプが必要なのであればPopen
のcommunicate()
メソッドを使ってください。
-
exception
subprocess.
CalledProcessError
¶ check_call()
またはcheck_output()
によって実行されるプロセスが非ゼロの終了ステータスを返す場合に送出される例外です。-
returncode
¶ 子プロセスの終了ステータスです。
-
cmd
¶ 子プロセスを spawn するために使用されるコマンドです。
-
output
¶ この例外が
check_output()
によって送出された場合は子プロセスの出力です。そうでなければNone
です。
-
17.1.1.1. よく使われる引数¶
幅広い使用例をサポートするために、 Popen
コンストラクタ (とその他の簡易関数) は、多くのオプション引数を受け付けます。典型的な使用例については、これらの引数の多くはデフォルト値のままで問題ありません。一般的に必要とされる引数は以下の通りです:
args は全ての呼び出しに必要で、文字列あるいはプログラム引数のシーケンスでなければなりません。一般に、引数のシーケンスを渡す方が望ましいです。なぜなら、モジュールが必要な引数のエスケープやクオート (例えばファイル名中のスペースを許すこと) の面倒を見ることができるためです。単一の文字列を渡す場合、 shell は
True
でなければなりません (以下を参照)。もしくは、その文字列は引数を指定せずに実行される単なるプログラムの名前でなければなりません。stdin, stdout および stderr には、実行するプログラムの標準入力、標準出力、および標準エラー出力のファイルハンドルをそれぞれ指定します。有効な値は
PIPE
、既存のファイルデスクリプタ (正の整数)、既存のファイルオブジェクト、そしてNone
です。PIPE
を指定すると新しいパイプが子プロセスに向けて作られます。デフォルト設定のNone
を指定するとリダイレクトは起こりません。子プロセスのファイルハンドルはすべて親から受け継がれます。 加えて、 stderr をSTDOUT
にすると、子プロセスの標準エラー出力からの出力は stdout と同じファイルハンドルに出力されます。stdout か stdout がパイプで universal_newlines が
True
の場合open()
関数への'U'
モードとして説明されている universal newlines モードで動作し、全ての行終端コードが'\n'
に変換されます。shell が
True
なら、指定されたコマンドはシェルによって実行されます。あなたが 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
) は、実行するプログラムとしてシェルを使用するかどうかを指定します。 shell がTrue
の場合、 args をシーケンスとしてではなく文字列として渡すことが推奨されます。Unix で
shell=True
の場合、シェルのデフォルトは/bin/sh
になります。 args が文字列の場合、この文字列はシェルを介して実行されるコマンドを指定します。したがって、文字列は厳密にシェルプロンプトで打つ形式と一致しなければなりません。例えば、文字列の中にスペースを含むファイル名がある場合は、クォーティングかバックスラッシュエスケープが必要です。 args がシーケンスの場合には、最初の要素はコマンド名を表わす文字列として、残りの要素は追加の引数としてシェルに渡されます。つまり、以下のPopen
と等価ということです:Popen(['/bin/sh', '-c', args[0], args[1], ...])
Windows で
shell=True
とすると、COMSPEC
環境変数がデフォルトシェルを指定します。 Windows でshell=True
を指定する必要があるのは、実行したいコマンドがシェルに組み込みの場合だけです (例えば dir や copy)。バッチファイルやコンソールベースの実行ファイルを実行するためにshell=True
は必要ありません。警告
shell=True
を渡すことは、信頼されていない入力と組み合わせるとセキュリティ上の脅威となり得ます。詳細については よく使われる引数 に含まれる警告を参照してください。bufsize は、もしこれが与えられた場合、ビルトインの open() 関数の該当する引数と同じ意味をもちます:
0
はバッファされないことを意味し、1
は行ごとにバッファされることを、それ以外の正の値は (ほぼ) その大きさのバッファが使われることを意味します。負の bufsize はシステムのデフォルト値が使われることを意味し、通常これはバッファがすべて有効となります。 bufsize のデフォルト値は0
(バッファされない) です。注釈
パフォーマンス上の問題がある場合、 bufsize を -1 か十分大きな正の値 (例えば 4096) に設定し、バッファを有効にすることを勧めます。
executable 引数は、実行される置換プログラムを指定します。これが必要になるのは極めて稀です。
shell=False
のときは、 executable は args で指定されている実行プログラムを置換します。しかし、オリジナルの args は依然としてプログラムに渡されます。ほとんどのプログラムは、 args で指定されたプログラムをコマンド名として扱います。そして、それは実際に実行されたプログラムとは異なる可能性があります。 Unix において、 ps のようなユーティリティの中では、 args 名が実行ファイルの表示名になります。shell=True
の場合、 Unix において executable 引数はデフォルトの/bin/sh
に対する置換シェルを指定します。stdin, stdout および stderr には、実行するプログラムの標準入力、標準出力、および標準エラー出力のファイルハンドルをそれぞれ指定します。有効な値は
PIPE
、既存のファイルデスクリプタ (正の整数)、既存のファイルオブジェクト、そしてNone
です。PIPE
を指定すると新しいパイプが子プロセスに向けて作られます。デフォルト設定のNone
を指定するとリダイレクトは起こりません。子プロセスのファイルハンドルはすべて親から受け継がれます。 加えて、 stderr をSTDOUT
にすると、子プロセスの標準エラー出力からの出力は stdout と同じファイルハンドルに出力されます。preexec_fn に callable オブジェクトが指定されている場合、このオブジェクトは子プロセスが起動されてから、プログラムが exec される直前に呼ばれます。(Unixのみ)
close_fds が true の場合、子プロセスが実行される前に
0
,1
,2
以外のすべてのファイルデスクリプタが閉じられます (Unixのみ)。 Windows では close_fds が true の場合、すべてのファイルハンドルは子プロセスに引き継がれません。 Windows の場合、 close_fds を true にしながら、 stdin, stdout, stderr を利用して標準ハンドルをリダイレクトすることはできません。cwd が
None
以外の場合、子プロセスのカレントディレクトリが実行される前に cwd に変更されます。このディレクトリは実行ファイルを探す段階では考慮されませんので、プログラムのパスを cwd に対する相対パスで指定することはできない、ということに注意してください。env が
None
以外の場合、これは新しいプロセスでの環境変数を定義します。デフォルトでは、子プロセスは現在のプロセスの環境変数を引き継ぎます。注釈
env を特定の値として与える場合、プログラムを実行するのに必要な変数全てを与えなければなりません。 Windows で side-by-side assembly を実行するためには、 env は正しい
SystemRoot
を 含まなければいけません 。universal_newlines を
True
にすると、ファイルオブジェクト stdout, stderr が universal 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.
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
¶ dwFlags
がSTARTF_USESTDHANDLES
を指定すれば、この属性がプロセスの標準入力処理です。STARTF_USESTDHANDLES
が指定されなければ、標準入力のデフォルトはキーボードバッファです。
-
hStdOutput
¶ dwFlags
がSTARTF_USESTDHANDLES
を指定すれば、この属性がプロセスの標準出力処理です。そうでなければ、この属性は無視され、標準出力のデフォルトはコンソールウィンドウのバッファです。
-
hStdError
¶ dwFlags
がSTARTF_USESTDHANDLES
を指定すれば、この属性がプロセスの標準エラー処理です。そうでなければ、この属性は無視され、標準エラーのデフォルトはコンソールウィンドウのバッファです。
-
wShowWindow
¶ dwFlags
がSTARTF_USESHOWWINDOW
を指定すれば、この属性は ShowWindow 関数のnCmdShow
引数で指定された値なら、SW_SHOWDEFAULT
以外の任意のものにできます。しかし、この属性は無視されます。この属性には
SW_HIDE
が提供されています。これは、Popen
がshell=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
¶ 新しいプロセスが、親プロセスのコンソールを継承する (デフォルト) のではなく、新しいコンソールを持ちます。
Popen
がshell=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
と同じです:
17.1.5. 注釈¶
17.1.5.1. Windows における引数シーケンスから文字列への変換¶
Windows では、 args シーケンスは以下の (MS C ランタイムで使われる規則に対応する) 規則を使って解析できる文字列に変換されます:
引数は、スペースかタブのどちらかの空白で分けられます。
ダブルクオーテーションマークで囲まれた文字列は、空白が含まれていたとしても 1 つの引数として解釈されます。クオートされた文字列は引数に埋め込めます。
バックスラッシュに続くダブルクオーテーションマークは、リテラルのダブルクオーテーションマークと解釈されます。
バックスラッシュは、ダブルクオーテーションが続かない限り、リテラルとして解釈されます。
複数のバックスラッシュにダブルクオーテーションマークが続くなら、バックスラッシュ 2 つで 1 つのバックスラッシュ文字と解釈されます。バックスラッシュの数が奇数なら、最後のバックスラッシュは規則 3 に従って続くダブルクオーテーションマークをエスケープします。