17.1. サブプロセス—サブプロセス管理—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/2.7/library/subprocess
移動先:案内検索

17.1。 サブプロセス —サブプロセス管理

バージョン2.4の新機能。


サブプロセスモジュールを使用すると、新しいプロセスを生成し、それらの入力/出力/エラーパイプに接続して、それらのリターンコードを取得できます。 このモジュールは、いくつかの古いモジュールと機能を置き換えることを目的としています。

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

このモジュールを使用して古い関数を置き換える方法については、 subprocess-replacements セクションを参照してください。

も参照してください

POSIXユーザー(Linux、BSDなど)は、Python 2.7に含まれているバージョンではなく、はるかに新しい subprocess32 モジュールをインストールして使用することを強くお勧めします。 これは、多くの状況でより良い動作への置き換えの低下です。

PEP 324 –サブプロセスモジュールを提案するPEP


17.1.1。 を使用してサブプロセスモジュール

サブプロセスを起動するための推奨される方法は、次の便利な関数を使用することです。 これらがニーズを満たさない、より高度なユースケースについては、基盤となる 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を使用すると、セキュリティ上の問題が発生する可能性があります。 詳細については、頻繁に使用される引数の警告を参照してください。

ノート

stdout=PIPEまたはstderr=PIPEをこの機能と一緒に使用しないでください。子プロセスの出力量に基づいてデッドロックが発生する可能性があります。 パイプが必要な場合は、 Popencommunicate()メソッドを使用してください。

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

引数を指定してコマンドを実行します。 コマンドが完了するのを待ちます。 戻りコードがゼロの場合は戻り、そうでない場合は 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を使用すると、セキュリティ上の問題が発生する可能性があります。 詳細については、頻繁に使用される引数の警告を参照してください。

ノート

stdout=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をこの関数と一緒に使用しないでください。子プロセスのエラー量に基づいて、デッドロックが発生する可能性があります。 stderrパイプが必要な場合は、 Popencommunicate()メソッドを使用します。

subprocess.PIPE
stdinstdout 、または stderr 引数として Popen に使用でき、標準ストリームへのパイプが必要であることを示す特別な値開かれます。
subprocess.STDOUT
Popenstderr 引数として使用でき、標準エラーが標準出力と同じハンドルに入る必要があることを示す特別な値。
exception subprocess.CalledProcessError

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

returncode

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

cmd

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

output

この例外が check_output()によって発生した場合の子プロセスの出力。 それ以外の場合は、None

17.1.1.1。 頻繁に使用される引数

さまざまなユースケースをサポートするために、 Popen コンストラクター(およびコンビニエンス関数)は、多数のオプションの引数を受け入れます。 最も一般的なユースケースでは、これらの引数の多くをデフォルト値のままにしておくことができます。 最も一般的に必要な引数は次のとおりです。

args はすべての呼び出しに必要であり、文字列または一連のプログラム引数である必要があります。 引数のシーケンスを提供することは、モジュールが引数の必要なエスケープと引用を処理できるようにするため、一般的に好まれます(例: ファイル名にスペースを入れるため)。 単一の文字列を渡す場合、 shellTrue (以下を参照)である必要があります。そうでない場合、文字列は引数を指定せずに実行するプログラムに名前を付ける必要があります。

stdinstdoutstderr は、それぞれ実行プログラムの標準入力、標準出力、標準エラーファイルハンドルを指定します。 有効な値は、 PIPE 、既存のファイル記述子(正の整数)、既存のファイルオブジェクト、およびNoneです。 PIPE は、子への新しいパイプを作成する必要があることを示します。 Noneのデフォルト設定では、リダイレクトは発生しません。 子のファイルハンドルは親から継承されます。 さらに、 stderrSTDOUT にすることができます。これは、子プロセスからのstderrデータをstdoutと同じファイルハンドルにキャプチャする必要があることを示します。

stdout または stderr がパイプで、 Universal_newlinesTrueの場合、すべての行末は'\n'に変換されます。 ユニバーサル改行 'U'モード引数 open()

shellTrueの場合、指定されたコマンドはシェルを介して実行されます。 これは、主にほとんどのシステムシェルで提供される拡張制御フローにPythonを使用していて、シェルパイプ、ファイル名ワイルドカード、環境変数の拡張、~の拡張などの他のシェル機能への便利なアクセスが必要な場合に役立ちます。 ]ユーザーのホームディレクトリに移動します。 ただし、Python自体が多くのシェルのような機能(特に、 globfnmatchos.walk()os)の実装を提供していることに注意してください。 .path.expandvars()os.path.expanduser()、および shutil )。

警告

信頼できないソースからのサニタイズされていない入力を組み込んだシェルコマンドを実行すると、プログラムがシェルインジェクションに対して脆弱になり、任意のコマンドが実行される可能性のある重大なセキュリティ上の欠陥になります。 このため、コマンド文字列が外部入力から作成される場合、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 クラスによって処理されます。 開発者が便利な関数でカバーされていないあまり一般的でないケースを処理できるように、それは多くの柔軟性を提供します。

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 が文字列の場合、その文字列は実行するプログラムの名前またはパスとして解釈されます。 ただし、これは、プログラムに引数を渡さない場合にのみ実行できます。

ノート

shlex.split()は、 args の正しいトークン化を決定するときに、特に複雑な場合に役立ちます。

>>> 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 をシーケンスではなく文字列として渡すことをお勧めします。

shell=Trueを使用するUnixでは、シェルのデフォルトは/bin/shです。 args が文字列の場合、文字列はシェルを介して実行するコマンドを指定します。 つまり、文字列は、シェルプロンプトで入力したときとまったく同じようにフォーマットする必要があります。 これには、たとえば、スペースを含むファイル名を引用符で囲んだり、円記号で囲んだりすることが含まれます。 args がシーケンスの場合、最初の項目はコマンド文字列を指定し、追加の項目はシェル自体への追加の引数として扱われます。 つまり、 Popen は次と同等の機能を果たします。

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

shell=Trueを搭載したWindowsでは、 COMSPEC環境変数がデフォルトのシェルを指定します。 Windowsでshell=Trueを指定する必要があるのは、実行するコマンドがシェルに組み込まれているときだけです(例: dir または copy )。 バッチファイルまたはコンソールベースの実行可能ファイルを実行するのにshell=Trueは必要ありません。

警告

shell=Trueを渡すと、信頼できない入力と組み合わせるとセキュリティ上の問題が発生する可能性があります。 詳細については、頻繁に使用される引数の警告を参照してください。

bufsize は、指定されている場合、組み込みのopen()関数に対応する引数と同じ意味を持ちます。0はバッファなしを意味し、1はバッファされた行を意味します。正の値は、(ほぼ)そのサイズのバッファーを使用することを意味します。 負の bufsize は、システムのデフォルトを使用することを意味します。これは通常、完全にバッファリングされていることを意味します。 bufsize のデフォルト値は0(バッファなし)です。

ノート

パフォーマンスの問題が発生した場合は、 bufsize を-1または十分に大きい正の値(4096など)に設定して、バッファリングを有効にすることをお勧めします。

executeable 引数は、実行する置換プログラムを指定します。 それはめったに必要とされません。 shell=Falseの場合、実行可能ファイルは、 args で指定された実行プログラムを置き換えます。 ただし、元の args は引き続きプログラムに渡されます。 ほとんどのプログラムは、 args で指定されたプログラムをコマンド名として扱います。コマンド名は、実際に実行されるプログラムとは異なる場合があります。 Unixでは、 args 名は、 ps などのユーティリティの実行可能ファイルの表示名になります。 shell=Trueの場合、Unixでは executeable 引数は、デフォルトの/bin/shの置換シェルを指定します。

stdinstdoutstderr は、それぞれ実行プログラムの標準入力、標準出力、標準エラーファイルハンドルを指定します。 有効な値は、 PIPE 、既存のファイル記述子(正の整数)、既存のファイルオブジェクト、およびNoneです。 PIPE は、子への新しいパイプを作成する必要があることを示します。 Noneのデフォルト設定では、リダイレクトは発生しません。 子のファイルハンドルは親から継承されます。 さらに、 stderrSTDOUT にすることができます。これは、子プロセスからのstderrデータをstdoutと同じファイルハンドルにキャプチャする必要があることを示します。

preexec_fn が呼び出し可能オブジェクトに設定されている場合、このオブジェクトは、子が実行される直前に子プロセスで呼び出されます。 (Unixのみ)

close_fds がtrueの場合、子プロセスが実行される前に、01、および2を除くすべてのファイル記述子が閉じられます。 (Unixのみ)。 または、Windowsでは、 close_fds がtrueの場合、子プロセスによってハンドルが継承されません。 Windowsでは、 close_fds をtrueに設定したり、 stdinstdout 、または stderr を設定して標準ハンドルをリダイレクトしたりすることはできません。

cwdNoneでない場合、子の現在のディレクトリは実行前に cwd に変更されます。 実行可能ファイルを検索するときにこのディレクトリは考慮されないため、 cwd を基準にしたプログラムのパスを指定できないことに注意してください。

envNoneでない場合は、新しいプロセスの環境変数を定義するマッピングである必要があります。 これらは、デフォルトの動作である現在のプロセスの環境を継承する代わりに使用されます。

ノート

指定する場合、 env は、プログラムの実行に必要な変数を提供する必要があります。 Windowsでは、サイドバイサイドアセンブリを実行するには、指定された env must に有効な SystemRootが含まれている必要があります。 ]。

Universal_newlinesTrueの場合、ファイルオブジェクト stdout および stderr は、ユニバーサルニューラインモードでテキストファイルとして開かれます。 行は、'\n'、Unixの行末規則、'\r'、古いMacintosh規則、または'\r\n'、Windows規則のいずれかで終了できます。 これらの外部表現はすべて、Pythonプログラムによって'\n'として認識されます。

ノート

この機能は、Pythonがユニバーサル改行サポート(デフォルト)で構築されている場合にのみ使用できます。 また、ファイルオブジェクト stdoutstdin 、および stderr の改行属性は、communicate()メソッドによって更新されません。

指定した場合、 startupinfoSTARTUPINFO オブジェクトになり、基になるCreateProcess関数に渡されます。 作成フラグは、指定されている場合、 CREATE_NEW_CONSOLE または CREATE_NEW_PROCESS_GROUP にすることができます。 (Windowsのみ)


17.1.1.3。 例外

新しいプログラムの実行が開始される前に、子プロセスで発生した例外は、親で再発生します。 さらに、例外オブジェクトには、child_tracebackと呼ばれる1つの追加属性があります。これは、子の観点からのトレースバック情報を含む文字列です。

発生する最も一般的な例外は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 属性を設定して返します。

警告

これは、stdout=PIPEまたはstderr=PIPE、あるいはその両方を使用するとデッドロックになり、子プロセスはパイプに十分な出力を生成して、OSパイプバッファーがより多くのデータを受け入れるのを待機するのをブロックします。 それを避けるために communicate()を使用してください。

Popen.communicate(input=None)

プロセスとの対話:データをstdinに送信します。 ファイルの終わりに達するまで、stdoutおよびstderrからデータを読み取ります。 プロセスが終了するのを待ちます。 オプションの input 引数は、子プロセスに送信する文字列であるか、データを子に送信しない場合はNoneである必要があります。

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

プロセスのstdinにデータを送信する場合は、stdin=PIPEを使用してPopenオブジェクトを作成する必要があることに注意してください。 同様に、結果タプルでNone以外のものを取得するには、stdout=PIPEまたはstderr=PIPE、あるいはその両方を指定する必要があります。

ノート

読み取られたデータはメモリにバッファリングされるため、データサイズが大きい場合や無制限の場合は、この方法を使用しないでください。

Popen.send_signal(signal)

シグナルシグナルを子に送信します。

ノート

Windowsでは、SIGTERMは terminate()のエイリアスです。 CTRL_C_EVENTおよびCTRL_BREAK_EVENTは、 CREATE_NEW_PROCESS_GROUP を含む creationflags パラメーターで開始されたプロセスに送信できます。

バージョン2.6の新機能。

Popen.terminate()

子供を止めなさい。 Posix OSでは、メソッドはSIGTERMを子に送信します。 Windowsでは、Win32API関数TerminateProcess()が呼び出されて子が停止します。

バージョン2.6の新機能。

Popen.kill()

子供を殺します。 Posix OSでは、関数はSIGKILLを子に送信します。 Windowsでは、 kill()terminate()のエイリアスです。

バージョン2.6の新機能。

次の属性も使用できます。

警告

.stdin.write.stdout.read.stderr.read ではなく、 communicate()を使用して、デッドロックを回避します。他のOSパイプバッファがいっぱいになり、子プロセスをブロックします。


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()によって(および communication()によって間接的に)設定される子の戻りコード。 None値は、プロセスがまだ終了していないことを示します。

負の値-Nは、子がシグナルN(Unixのみ)によって終了したことを示します。


17.1.3。 WindowsPopenヘルパー

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.STD_INPUT_HANDLE
標準の入力デバイス。 最初は、これはコンソール入力バッファーCONIN$です。
subprocess.STD_OUTPUT_HANDLE
標準出力デバイス。 最初は、これはアクティブなコンソール画面バッファーCONOUT$です。
subprocess.STD_ERROR_HANDLE
標準エラーデバイス。 最初は、これはアクティブなコンソール画面バッファーCONOUT$です。
subprocess.SW_HIDE
ウィンドウを非表示にします。 別のウィンドウがアクティブになります。
subprocess.STARTF_USESTDHANDLES
STARTUPINFO.hStdInputSTARTUPINFO.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。 古い関数をサブプロセスモジュール

このセクションで「aがbになる」とは、bをaの代わりに使用できることを意味します。

ノート

このセクションのすべての「a」関数は、実行されたプログラムが見つからない場合、(多かれ少なかれ)サイレントに失敗します。 「b」の置換では、代わりにOSErrorが発生します。

さらに、 check_output()を使用した置換は、要求された操作でゼロ以外の戻りコードが生成された場合、 CalledProcessError で失敗します。 出力は、発生した例外の output 属性として引き続き使用できます。


以下の例では、関連する関数がサブプロセスモジュールからすでにインポートされていることを前提としています。

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の前に存在する場合、p1がSIGPIPEを受信するには、p2の開始後のp1.stdout.close()呼び出しが重要です。

または、信頼できる入力の場合、シェル自体のパイプラインサポートを直接使用することもできます。

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 は、実行が失敗した場合に例外を発生させます。
  • captionstderr 引数は stderr 引数に置き換えられます。
  • stdin=PIPEおよびstdout=PIPEを指定する必要があります。
  • popen2はデフォルトですべてのファイル記述子を閉じますが、[X81X] を Popen で指定する必要があります。


17.1.5。 ノート

17.1.5.1。 Windowsで引数シーケンスを文字列に変換する

Windowsでは、 args シーケンスは、次のルール(MS Cランタイムで使用されるルールに対応)を使用して解析できる文字列に変換されます。

  1. 引数は、スペースまたはタブのいずれかである空白で区切られます。
  2. 二重引用符で囲まれた文字列は、空白が含まれているかどうかに関係なく、単一の引数として解釈されます。 引用符で囲まれた文字列を引数に埋め込むことができます。
  3. バックスラッシュが前に付いた二重引用符は、リテラルの二重引用符として解釈されます。
  4. バックスラッシュは、二重引用符の直前にない限り、文字通りに解釈されます。
  5. バックスラッシュが二重引用符の直前にある場合、バックスラッシュのすべてのペアはリテラルのバックスラッシュとして解釈されます。 バックスラッシュの数が奇数の場合、ルール3で説明されているように、最後のバックスラッシュは次の二重引用符をエスケープします。