2017-01-16 12 views
2

どちらもサブプロセスを実行し、パイプを作成して入出力を行うように見えますが、サブプロセスが新しいものにすぎません。Python:いつos.popenの代わりにsubprocess.Popenを使うべきですか?

私の質問は、subprocess.Popenはos.popenではできないが、新しいサブプロセスが必要な機能はありますか?

なぜ、python言語はos.popenを拡張することを選択しなかったが、新しいモジュールを作成したのですか?

おかげ

+4

https://docs.python.org/2/library/os.html#os.popenから "バージョン2.6より非推奨:この機能は廃止されました。サブプロセスモジュールを使用してください。" –

+2

https://www.pythonを参照してください。org/dev/peps/pep-0324/Motivation&Rationaleセクション:セキュリティリスク、孤立プロセス例外、ファイル記述子によるより良い操作などから保護します。 –

+1

安全性と信頼性の問題以外にも、 popen'家族は扱いにくく混乱しました。あなたがコーディングしている間にドキュメントをよく参照せずに正しく使用することはほとんど不可能でした。これとは対照的に、 'subprocess'は神の贈り物ですが、それを使っている間はドキュメントを参照するのが賢明です。 ;) –

答えて

6

短い答え:subprocessを使用し、常に、os.popen絶対に使用しないでください!

あなたは、Python 2.7 os.popen docsから見ることができるように:

は、バージョン2.6で撤廃:この関数は廃止されました。 subprocessモジュールを使用してください。特に Replacing Older Functions with the subprocess Moduleセクションを確認してください。

古いos.popenファミリの機能にはさまざまな制限と問題がありました。そして、ドキュメントが言及しているように、2.6以前のバージョンはWindows上でさえ信頼できませんでした。

subprocessの背後にある動機はPEP 324 -- subprocess - New process moduleで説明されています。新しいプロセスを起動する

動機

はPythonのような高級言語で一般的な任意のプログラミング言語、 におけるタスクと非常に一般的です。良いサポートが のために、このタスクは、必要とされている理由は次のとおりです。

    セキュリティリスクを意味するかもしれないプロセスを起動するための
  • 不適切な機能:プログラムはシェルから起動し、 されている場合は、引数はシェルのメタ文字を含む、結果を可能性があります 悲惨です。 [1]

  • これは、複雑なシェルスクリプト のPythonをより良い代替言語にします。

現在のところ、Pythonはプロセスの作成に多くの異なる機能を備えています。これにより、開発者が選択するのが難しくなります。

サブプロセスモジュールは 以前の機能の上に次の拡張機能を提供する:

  • つの「統一」モジュールは、前 関数からのすべての機能を提供します。

  • クロスプロセスの例外:新しいプロセスの前に子 で起こった例外は 親に再提起されている実行を開始しました。つまり、例えばexec() の失敗を処理するのは簡単です。たとえば、popen2では、実行が失敗した場合は検出することが不可能です( )。

  • forkとexecの間でカスタムコードを実行するためのフック。この は、たとえばuidの変更に使用できます。

  • /bin/shの暗黙の呼び出しはありません。つまり、危険なシェルのメタ文字をエスケープするためには、 は必要ありません。

  • ファイル記述子リダイレクトのすべての組み合わせが可能です。 たとえば、 "python-dialog" [2]はプロセス を生成し、stderrをリダイレクトする必要がありますが、stdoutはリダイレクトする必要がありません。テンポラリファイルを使用しないで、 現在の機能ではこれは不可能です。 subprocessモジュールで

  • 、それは新しいプログラムが実行 である前に、開いているすべての ファイルディスクリプタをクローズする必要がある場合に制御することが可能です。

  • 複数のサブプロセス(シェル "パイプ")の接続をサポートしています。

  • ユニバーサル改行をサポートしています。それは簡単なデッドロックを危険にさらすことなく、STDINデータ を送信し、stdoutとstderrデータを読み出すことができる

  • Aが通信()メソッド。 ほとんどの人は、 子プロセス通信に関連するフロー制御の問題を認識していますが、すべてが忍耐力または のスキルを持っているわけではありません。 これは、多くのPythonアプリケーションにレース 条件が含まれていることを意味します。標準ライブラリ のA()メソッドはこの問題を解決します。

PEP根拠のリンク、および更なる詳細をご覧ください。

安全性の問題&信頼性の問題とは別に、IMHOの古いos.popenファミリは煩雑で混乱しました。あなたがコーディングしている間にドキュメントをよく参照せずに正しく使用することはほとんど不可能でした。これと比較して、subprocessは神託ですが、ドキュメントを使用している間はドキュメントを参照するのが賢明です。 ;)

ときどきsubprocess.Popenではなく、subprocess.Popenの使用を推奨する人がPython 2.7で表示されます(例:Python subprocess vs os.popen overhead)。確かに高速ですが、それは安全に動作することを保証するために不可欠なさまざまなことを行わないためです。


FWIW、os.popen itself still exists in Python 3は、しかし、それが安全にsubprocess.Popenを経て実現していますので、あなたにもちょうど直接自分でsubprocess.Popenを使用する場合があります。 os.popenファミリの他のメンバーは、Python 3には存在しなくなりました。os.spawnファミリの機能はPython 3にはまだ存在しますが、代わりにsubprocessモジュールが提供するより強力な機能を使用することをお勧めします。

関連する問題