2012-12-12 14 views
7

Próbowałem zrozumieć, dlaczego tak się dzieje. Wzywam polecenie ponownego uruchomienia sieci na serwerze Ubuntu 12.04.Podproces Pythona check_output dużo wolniej niż zadzwoń

Szybkie wykonanie

Kiedy zadzwonić do komendy przy użyciu jednej z następujących trzech sposobów trwa około 0,1 sekundy, aby wykonać:

  1. bezpośrednio w terminalu
  2. skrypt Pythona przy użyciu os.system
  3. skrypt python używający subprocess.call

zacisk sesja:

[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 

Powolne wykonanie

Jednak jeśli używam subprocess.check_output lub POPEN i spróbować odczytać wyjście potrzebny 23 sekund. O wiele wolniej. Wydaje się, że ta dramatyczna różnica występuje tylko wtedy, gdy próbuję użyć funkcji, która zwróci wynik polecenia. Chciałbym zrozumieć, dlaczego tak się dzieje i znaleźć rozwiązanie, aby wykonać to polecenie i uzyskać jego wyniki, jeśli nie zajmie to dużo czasu.

zacisk sesja:

[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 

Aktualizacja

Jeden z komentarzy sugeruje wypróbowanie polecenia tee. Wyniki są bardzo interesujące. W terminalu bez udziału pytona, jeśli używa się tee, zajmuje to samo 23 sekundy. Wciąż jestem ciekawy dlaczego, ale przynajmniej może to dać więcej wskazówek co do tego, co się dzieje.

+0

ja nie wiem, czy jedną z następujących czynności jest istotna ([pytanie # 10150368] (http://stackoverflow.com/questions/10150368/why-is-piping-output-of-subprocess-so - niezwiązany z pythonem), [pytanie # 4940607] (http://stackoverflow.com/questions/4940607/python-subprocesses-experience-mysterious-delay-in-receiving-stdin-eof)), ale jedna odpowiedź sugeruje dodanie 'close_fds = True' do parametrów popen –

+0

' subprocess.call() 'jest po prostu' subprocess.Popen (* popenargs, ** kwargs) .wait() '. – Blender

+0

@ jwpat7 dzięki za linki. Próbowałem close_fds = True, ale to nie miało znaczenia. –

Odpowiedz

8

Poniższy kod bazuje na doskonałym komentarzu J.F. Sebastian. Poniższy kod jest uruchamiany w 0,1 sekundy zgodnie z oczekiwaniami i zwraca wynik polecenia do łańcucha.

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() 
Powiązane problemy