使用子进程执行命令的区别

时间:2015-05-12 18:55:35

标签: python subprocess

我有一段执行良好的代码:

import subprocess

exe_cmd = subprocess.Popen(["ls", "-al"], stdout=subprocess.PIPE)
output, err = exe_cmd.communicate()
print output

我还有另一篇文章,我将命令分配给变量,然后将其作为参数传递。但在这种情况下,它失败了。为什么呢?

import subprocess

#Here I assign the command to a variable.

cmd = "ls -al" 
exe_cmd = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output, err = exe_cmd.communicate()
print output

3 个答案:

答案 0 :(得分:3)

如果要将字符串用作Popen的第一个参数,则需要在调用中设置shell=True。否则,它会尝试查找带有完整字符串的可执行文件并运行它,在这种情况下当然不存在。

答案 1 :(得分:2)

你的cmd变量应该是

cmd = ["ls","-al" ]

documentation

清楚地表明了这一点
  

在Unix上,如果args是一个字符串, 该字符串将被解释为要执行的程序的名称或路径 。但是,只有在不将参数传递给程序时才能执行此操作。

所以你需要设置shell=True

  

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

(强调我的)

答案 2 :(得分:1)

Popen的第一个参数是一个参数列表,在你传递它的第一个例子中 在你的第二个例子中,["ls", "-al"]你传递了一个字符串" ls -al"。

您可以更改将["ls", "-al"]分配给cmd的代码。

您还可以使用shlex.split来解析字符串并将列表传递给Popen