Python subprocess Popen parameter difference
What's the difference between
subpr开发者_开发百科ocess.Popen(['cat','/path/to/file'], stdout=subprocess.PIPE, shell=True)
and
subprocess.Popen(['cat '+'/path/to/file'], stdout=subprocess.PIPE, shell=True)
? I'm doing this in ipython. For the first one, ipython just hang. Maybe not hang, but it's significantly slower. The second is just OK.
Just don't know why.
The first one is actually only running cat
(because of the way that the command is parsed if you use shell = True
), and thus hanging because it's waiting for input. The second one is running cat /path/to/file
. You can see this by doing:
>>> 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
Versus doing it with 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
If you set shell = True
, passing a list as args
won't get you the behaviour you want - you need to pass a string.
i tested the samples and found that the first worked returning a Popen object in ipython but the second did the same but printed cat: /path/to/file: No such file or directory
i like to avoid using subprocess.Popen
with shell=True
when possible and use a list ['x', '--version']
as this avoids the need to quote path names with say ` graves in them or some such muck
in a patch to pymp.py i changed:
p = subprocess.Popen(['mplayer -slave -quiet \'' + target + '\' -include \'' + MPLAYERCONFFILE + '\' 2>/dev/null'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
to:
devnull = open('/dev/null', 'w')
p = subprocess.Popen(['mplayer', '-slave', '-quiet', target, '-include', MPLAYERCONFFILE], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=devnull)
精彩评论