2012-12-12 6 views
7

なぜこれが起こっているのか理解しようとしていました。私は、Ubuntuサーバー12.04でネットワークを再起動するコマンドを呼び出しています。Pythonのサブプロセスcheck_outputの方がはるかに遅いです。

高速実行

私はそれを実行するために周りに0.1秒かかり三つの方法以下のいずれかを使用してコマンドを呼び出すと:os.system

  • を使用して
  • ターミナルPythonスクリプトに直接

    1. をPythonスクリプトを使用してsubprocess.call

    端末セッション:私はsubprocess.check_outputやpopenのを使用して出力を試してみて、読めば

    [email protected]:~# time /etc/init.d/networking restart 
    * Running /etc/init.d/networking restart 
    * Reconfiguring network interfaces... 
    real 0m0.105s 
    
    [email protected]:~# time python -c "import os; 
    > os.system('/etc/init.d/networking restart')" 
    * Running /etc/init.d/networking restart 
    * Reconfiguring network interfaces... 
    real 0m0.111s 
    
    [email protected]:~# time python -c "import subprocess; 
    > subprocess.call(['/etc/init.d/networking', 'restart'])" 
    * Running /etc/init.d/networking restart 
    * Reconfiguring network interfaces... 
    real 0m0.111s 
    

    スロー実行

    は、しかし、それは23秒かかります。遅い方。この劇的な違いは、コマンドの出力を返す関数を試してみると発生します。私はなぜこれが起こっているのか理解し、このコマンドを実行するソリューションを見つけて、長時間かかることなく出力を得ることができます。

    端末セッション:

    [email protected]:~# time python -c "import subprocess; 
    > print subprocess.check_output(['/etc/init.d/networking', 'restart'])" 
    * Running /etc/init.d/networking restart 
    * Reconfiguring network interfaces... 
    real 0m23.201s 
    
    [email protected]:~# time python -c "from subprocess import Popen, PIPE; 
    > print Popen(['/etc/init.d/networking', 'restart'], stdout=PIPE).stdout.read()" 
    * Running /etc/init.d/networking restart 
    * Reconfiguring network interfaces... 
    real 0m23.201s 
    

    更新

    コメントの一つは、teeコマンドを実行しようと提案しました。結果は非常に興味深いところです。ティーが使用されている場合、パイソンの関与のない端末では、同じ23秒かかる。私はまだ不思議ですが、少なくともこれは何が起こっているかについてより多くの手がかりを与えるかもしれません。

    [email protected]:~# time /etc/init.d/networking restart | tee out.txt 
    * Running /etc/init.d/networking restart 
    * Reconfiguring network interfaces... 
    real 0m23.181s 
    
    +0

    次のいずれかに該当する場合、私は知りません([質問#10150368](http://stackoverflow.com/questions/10150368/why-is-piping-output-of-subprocess-so -unreliable-with-python)、[question#4940607](http://stackoverflow.com/questions/4940607/python-subprocesses-experience-mysterious-delay-in-receiving-stdin-eof))しかし、1つの答えは、 –

    +0

    'subprocess.call()'は単に 'subprocess.Popen(* popenargs、** kwargs).wait()'です。 – Blender

    +0

    @ jwpat7リンクに感謝します。私はclose_fdsを試した=真実は違いをもたらさなかった。 –

    答えて

    8

    以下のコードは、J.F. Sebastianが作成した優れたコメントに基づいています。以下のコードは期待どおり0.1秒で実行され、コマンドの出力を文字列に返します。

    from subprocess import check_call, STDOUT 
    from tempfile import NamedTemporaryFile 
    
    with NamedTemporaryFile() as f: 
        check_call(['/etc/init.d/networking', 'restart'], stdout=f, stderr=STDOUT) 
        f.seek(0) 
        output = f.read() 
    
    関連する問題