なぜこれが起こっているのか理解しようとしていました。私は、Ubuntuサーバー12.04でネットワークを再起動するコマンドを呼び出しています。Pythonのサブプロセスcheck_outputの方がはるかに遅いです。
高速実行
私はそれを実行するために周りに0.1秒かかり三つの方法以下のいずれかを使用してコマンドを呼び出すと:os.system
- を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
次のいずれかに該当する場合、私は知りません([質問#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つの答えは、 –
'subprocess.call()'は単に 'subprocess.Popen(* popenargs、** kwargs).wait()'です。 – Blender
@ jwpat7リンクに感謝します。私はclose_fdsを試した=真実は違いをもたらさなかった。 –