Python子进程Popen参数差异

Python子进程Popen参数差异,python,subprocess,Python,Subprocess,两者之间有什么区别 subprocess.Popen(['cat','/path/to/file'], stdout=subprocess.PIPE, shell=True) 及 ?? 我在伊皮顿做这件事。 对于第一个,ipython只是挂断。可能不会挂起,但速度要慢得多。 第二个就可以了 只是不知道为什么。第一个命令实际上只运行了cat(因为如果使用shell=True,命令的解析方式是这样的),因此挂起,因为它正在等待输入。第二个正在运行cat/path/to/file。您可以通过以下操作

两者之间有什么区别

subprocess.Popen(['cat','/path/to/file'], stdout=subprocess.PIPE, shell=True)

?? 我在伊皮顿做这件事。 对于第一个,ipython只是挂断。可能不会挂起,但速度要慢得多。 第二个就可以了


只是不知道为什么。

第一个命令实际上只运行了
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
,将列表作为
args
传递不会得到您想要的行为-您需要传递一个字符串。

第一个命令实际上只运行
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
,将列表作为
args
传递不会得到您想要的行为-您需要传递一个字符串。

我测试了样本,发现第一个成功地在ipython中返回了Popen对象,但第二个成功,但打印了
cat:/path/to/file:没有这样的文件或目录

我喜欢尽可能避免使用
subprocess.Popen
shell=True
,并使用一个列表
['x','--version']
,因为这样可以避免引用路径名,比如说“graves”或类似的muck

在pymp.py的补丁中,我更改了:

p = subprocess.Popen(['mplayer -slave -quiet \'' + target + '\' -include \'' + MPLAYERCONFFILE + '\' 2>/dev/null'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
致:


我测试了样本,发现第一个在ipython中返回Popen对象有效,但第二个同样有效,但打印了
cat:/path/to/file:没有这样的文件或目录

我喜欢尽可能避免使用
subprocess.Popen
shell=True
,并使用一个列表
['x','--version']
,因为这样可以避免引用路径名,比如说“graves”或类似的muck

在pymp.py的补丁中,我更改了:

p = subprocess.Popen(['mplayer -slave -quiet \'' + target + '\' -include \'' + MPLAYERCONFFILE + '\' 2>/dev/null'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
致:


那么,你的意思是,对于第一个str,列表中的第二个str被忽略了?@wliao:阅读有关
shell=True
的内容。它运行shell中给定的字符串;所以,如果说有什么不同的话,那就是当给出一个列表时,它居然能工作,这有点令人惊讶。建议不要设置
shell=True
并给出列表。
shell=True
通常都是有害的,有时也是必须的。但是,如果您要提供文件的完整路径,那么您的命令没有理由设置
shell=True
,只需提供
cat
的完整路径即可。那么,您的意思是,对于第一个命令,列表中的第二个str被忽略?@wliao:阅读有关
shell=True
的内容。它运行shell中给定的字符串;所以,如果说有什么不同的话,那就是当给出一个列表时,它居然能工作,这有点令人惊讶。建议不要设置
shell=True
并给出列表。
shell=True
通常都是有害的,有时也是必须的。但是,如果要提供文件的完整路径,则使用命令没有理由设置
shell=True
,只需提供
cat
的完整路径即可。
devnull = open('/dev/null', 'w')
p = subprocess.Popen(['mplayer', '-slave', '-quiet', target, '-include', MPLAYERCONFFILE], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=devnull)