私はそれらの両方のドキュメントを見てきました。
この質問は、ここでのJ.F.のコメントによって促されます: subprocess.call()の出力を取得する
現在のPythonドキュメント subprocess.call()
は、subprocess.call()
にPIPE
を使用することについて次のように述べています。
注この関数では、_
stdout=PIPE
_または_stderr=PIPE
_を使用しないでください。パイプが読み取られていないため、OSパイプバッファをいっぱいにするのに十分な出力がパイプに生成されると、子プロセスはブロックされます。
Python 2.7 subprocess.call()
:
注この関数では、_
stdout=PIPE
_または_stderr=PIPE
_を使用しないでください。子プロセスの出力ボリュームに基づいてデッドロックが発生する可能性があります。パイプが必要な場合は、communication()メソッドでPopenを使用します。
Python2.6にはそのような警告は含まれていません。
また、 subprocess.call()
およびsubprocess.check_call()
は、communicate()でstdout = PIPEを使用する場合を除いて、出力にアクセスする方法がないようです。
https://docs.python.org/2.6/library/subprocess.html#convenience-functions
プロセスの
stdin
にデータを送信する場合は、_stdin=PIPE
_を使用してPopen
オブジェクトを作成する必要があることに注意してください。同様に、結果のタプルでNone以外のものを取得するには、_stdout=PIPE
_および/または_stderr=PIPE
_も指定する必要があります。
https://docs.python.org/2.6/library/subprocess.html#subprocess.Popen.communicate
subprocess.call()
とsubprocess.Popen()
の違いは、PIPE
のsubprocess.call()
の安全性を低下させますか?
より具体的:なぜsubprocess.call()
"子プロセスの出力ボリュームに基づくデッドロック。"、ではなくPopen()
?
call()
はPopen().wait()
(±エラー処理) です。
_stdout=PIPE
_をcall()
と一緒に使用しないでください。パイプから読み取られないため、子プロセスがハングします。対応するOSパイプバッファがいっぱいになるとすぐに。これは、データが_command1 | command2
_シェルパイプラインでどのように流れるかを示す図です。
あなたのPythonバージョンが何であるかは関係ありません-パイプバッファ(写真を見てください)はあなたのPythonプロセスの外にあります。Python 3はCstdioを使用しませんが、内部バッファリングにのみ影響します。内部バッファがフラッシュされると、データはパイプに送られます。_command2
_(親Python =プログラム)がパイプから読み取らない場合、_command1
_(たとえば、call()
によって開始される子プロセス)は、パイプバッファがいっぱいになるとすぐにハングします( pipe_size = fcntl(p.stdout, F_GETPIPE_SZ)
Linuxボックスで〜65K(最大値は_/proc/sys/fs/pipe-max-size
_ 〜1M))。
後でパイプから読み取る場合、たとえばPopen.communicate()
メソッドを使用する場合は、_stdout=PIPE
_を使用できます。 _process.stdout
_(パイプを表すファイルオブジェクト)から直接読み取る も可能です。
call
とPopen
はどちらも、コマンドの出力にアクセスする手段を提供します。
Popen
を使用すると、communicate
を使用するか、ファイル記述子またはファイルオブジェクトをstdout=...
パラメーターに指定できます。call
を使用する場合、唯一のオプションは、ファイル記述子またはファイルオブジェクトをstdout=...
パラメーターに渡すことです(これでcommunicate
を使用することはできません)。call
と一緒に使用したときにstdout=PIPE
が安全でない理由は、サブプロセスが終了するまでcall
が返されないためです。つまり、すべての出力がメモリに存在する必要があります。その瞬間まで、そして出力の量が多すぎると、OSパイプのバッファがいっぱいになります。
上記の情報を検証できるリファレンスは次のとおりです。
call
とPopen
の両方のパラメータは同じです。上記の引数は、以下の「頻繁に使用される引数」で説明されている最も一般的な引数にすぎません(したがって、省略された署名の表記は少し奇妙です)。完全な関数シグネチャは、Popenコンストラクタのシグネチャと同じです。この関数は、指定されたすべての引数をそのインターフェイスに直接渡します。
stdout
パラメータの可能な値は次のとおりです。有効な値は、PIPE、既存のファイル記述子(正の整数)、既存のファイルオブジェクト、およびNoneです。 PIPEは、子への新しいパイプを作成する必要があることを示します