Python subprocess Popen参数区别
这两个代码块有什么区别呢?
subprocess.Popen(['cat','/path/to/file'], stdout=subprocess.PIPE, shell=True)
和
subprocess.Popen(['cat '+'/path/to/file'], stdout=subprocess.PIPE, shell=True)
?我在使用ipython的时候遇到这个问题。
第一个代码块运行的时候,ipython就卡住了。可能不是完全卡住,但速度明显慢了很多。
而第二个代码块运行得就挺正常的。
我就是搞不懂为什么会这样。
2 个回答
0
我测试了一些示例,发现第一个示例在ipython中返回了一个Popen对象,而第二个示例也返回了一个Popen对象,但打印出了cat: /path/to/file: No such file or directory
的错误信息。
我喜欢尽量避免在使用subprocess.Popen
时加上shell=True
,而是使用像['x', '--version']
这样的列表,这样就不需要处理路径名中可能出现的特殊字符,比如反引号之类的麻烦。
在对pymp.py的一个补丁中,我把:
p = subprocess.Popen(['mplayer -slave -quiet \'' + target + '\' -include \'' + MPLAYERCONFFILE + '\' 2>/dev/null'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
改成了:
devnull = open('/dev/null', 'w')
p = subprocess.Popen(['mplayer', '-slave', '-quiet', target, '-include', MPLAYERCONFFILE], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=devnull)
4
第一个情况实际上只是运行了 cat
命令(因为当你使用 shell = True
时,命令的解析方式),所以它会一直挂着,因为它在等待输入。第二个情况是运行 cat /path/to/file
。你可以通过以下方式查看这个情况:
>>> subprocess.Popen(['ls', '-l'])
<subprocess.Popen object at 0x10048bdd0>
>>> total 8
-rw------- 1 root wheel 652 Nov 29 09:07 000d94cfc78b4
srwxr-xr-x 1 nbastin wheel 0 Nov 29 09:06 ics179
srwxr-xr-x 1 nbastin wheel 0 Nov 29 09:06 icssuis501
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launch-3ZniHd
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launch-8QRgz2
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launch-M5ppWp
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launchd-137.ztQAmI
drwx------ 2 nbastin wheel 68 Nov 29 09:57 ssh-LreGlOZPAR
而如果你使用 shell = True
的话,效果就不一样了:
>>> subprocess.Popen(['ls', '-l'], shell = True)
<subprocess.Popen object at 0x10048bd90>
>>> 000d94cfc78b4 ics179 icssuis501 launch-3ZniHd launch-8QRgz2 launch-M5ppWp launchd-137.ztQAmI ssh-LreGlOZPAR
如果你设置了 shell = True
,那么传递一个列表作为 args
是无法得到你想要的效果的——你需要传递一个字符串。