13

我正在尝试使用子进程执行简单的回显操作:

import subprocess
import shlex

cmd = 'echo $HOME'
proc = subprocess.Popen(shlex.split(cmd), shell=True, stdout=subprocess.PIPE)
print proc.communicate()[0]

但它什么也没打印。即使我将命令更改为echo "hello, world"它仍然不打印任何内容。任何帮助表示赞赏。

4

2 回答 2

17

在 Unix 上shell=True意味着第二个和后面的参数用于 shell 本身,使用字符串将命令传递给 shell:

import subprocess

cmd = 'echo $HOME'
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
print proc.communicate()[0],

你也可以这样写:

import subprocess

cmd = 'echo $HOME'
print subprocess.check_output(cmd, shell=True),

子流程的文档中

在带有 的 Unix 上shell=True,shell 默认为 /bin/sh。如果 args 是字符串,则该字符串指定要通过 shell 执行的命令。这意味着字符串的格式必须与在 shell 提示符下键入时的格式完全相同。这包括,例如,引用或反斜杠转义文件名,其中包含空格。如果 args 是一个序列,第一项指定命令字符串,任何附加项将被视为 shell 本身的附加参数。也就是说,Popen 相当于:

Popen(['/bin/sh', '-c', args[0], args[1], ...])
于 2013-06-21T02:51:46.010 回答
1

您混淆了 Popen 的两种不同调用。这些中的任何一个都可以工作:

proc=subprocess.Popen(['/bin/echo', 'hello', 'world'], shell=False, stdout=subprocess.PIPE)

或者

proc=subprocess.Popen('echo hello world', shell=True, stdout=subprocess.PIPE)

当传递 shell=True 时,第一个参数是一个字符串——shell 命令行。不使用 shell 时,第一个参数是一个列表。两者都产生这个:

print proc.communicate()
('hello world\n', None)
于 2014-05-14T23:07:31.710 回答