Python子进程check_输出比调用慢得多
我想知道为什么会这样。我正在调用一个命令来重新启动Ubuntu服务器12.04上的网络 快速执行 当我使用以下三种方式之一调用命令时,执行大约需要0.1秒:Python子进程check_输出比调用慢得多,python,performance,subprocess,Python,Performance,Subprocess,我想知道为什么会这样。我正在调用一个命令来重新启动Ubuntu服务器12.04上的网络 快速执行 当我使用以下三种方式之一调用命令时,执行大约需要0.1秒: 直达终点站 使用os.system的python脚本 使用子流程调用的python脚本 终端会话: root@ubuntu:~# time /etc/init.d/networking restart * Running /etc/init.d/networking restart * Reconfiguring network int
os.system的python脚本
子流程调用的python脚本
root@ubuntu:~# time /etc/init.d/networking restart
* Running /etc/init.d/networking restart
* Reconfiguring network interfaces...
real 0m0.105s
root@ubuntu:~# time python -c "import os;
> os.system('/etc/init.d/networking restart')"
* Running /etc/init.d/networking restart
* Reconfiguring network interfaces...
real 0m0.111s
root@ubuntu:~# time python -c "import subprocess;
> subprocess.call(['/etc/init.d/networking', 'restart'])"
* Running /etc/init.d/networking restart
* Reconfiguring network interfaces...
real 0m0.111s
root@ubuntu:~# 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
root@ubuntu:~# 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
执行缓慢
但是,如果我使用子流程,请检查\u output
或Popen并尝试读取输出,这需要23秒。慢多了。似乎只有当我尝试使用一个返回命令输出的函数时,这种巨大的差异才会发生。我想了解为什么会发生这种情况,并找到一个解决方案来执行这个命令并获得它的输出,而不需要花费太长时间
终端会话:
root@ubuntu:~# time /etc/init.d/networking restart
* Running /etc/init.d/networking restart
* Reconfiguring network interfaces...
real 0m0.105s
root@ubuntu:~# time python -c "import os;
> os.system('/etc/init.d/networking restart')"
* Running /etc/init.d/networking restart
* Reconfiguring network interfaces...
real 0m0.111s
root@ubuntu:~# time python -c "import subprocess;
> subprocess.call(['/etc/init.d/networking', 'restart'])"
* Running /etc/init.d/networking restart
* Reconfiguring network interfaces...
real 0m0.111s
root@ubuntu:~# 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
root@ubuntu:~# 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命令。结果很有趣。在没有python参与的终端中,如果使用tee,则需要同样的23秒。我仍然很好奇为什么,但至少这可能会提供更多关于发生了什么的线索
root@ubuntu:~# time /etc/init.d/networking restart | tee out.txt
* Running /etc/init.d/networking restart
* Reconfiguring network interfaces...
real 0m23.181s
下面的代码基于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()
我不知道以下两项是否相关(,),但有一个答案建议将
close_fds=True
添加到popen参数subprocess.call()
只是subprocess.popen(*popenargs,**kwargs)。wait()
@jwpat7谢谢链接。我尝试了close_fds=True,但没有任何区别。执行所需的时间:网络重启|打开某个_文件
(检查某个_文件是否为空)。尝试bufsize=-1
和/或f=TemporaryFile();检查调用(cmd,stdout=f,stderr=stdout);f、 寻求(0);output=f.read()
@J.f.Sebastian这些建议太棒了。我在问题中发布了tee的结果,输出的文件不是空的,它包含输出。你的临时文件方法非常有效。如果你把它贴在下面,我可以投你一票。我还是不明白为什么会发生这种事。