为什么我的变量不包含在我的subprocess.Popen中?

时间:2014-10-24 19:12:33

标签: python subprocess

我只是尝试将变量传递给我的shell脚本,但它并没有被移交。我'已经 以下来自python docs的示例,但它不起作用。我错过了什么?

subprocess.Popen(['./script.sh' + variable] , shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

4 个答案:

答案 0 :(得分:2)

除非您希望执行变量(例如shell=True)中的任何实际shell语法,否则您不应该在此使用>file.log

subprocess.Popen(['./script.sh', variable],
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)

如果确实想要shell=True,您可以选择安全地执行此操作。第一种是使用pipes.quote()(或者,在Python 3中,shlex.quote())来防止shell转义:

subprocess.Popen('./script.sh ' + pipes.quote(variable), shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)

第二种是将名称作为后续参数传递(注意空字符串,它在生成的shell中变为$0):

subprocess.Popen(['./script.sh "$1"', '', variable], shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)

请记住,Bobby Tables并不仅仅适用于SQL - 他的妹妹 Susan $(rm -rf /)也在那里。

答案 1 :(得分:1)

./ script.sh 之后添加空格:

subprocess.Popen(['./script.sh ' + variable] , shell=True, stdout=subprocess.PIPE,  stderr=subprocess.STDOUT)

答案 2 :(得分:1)

您将两种不同的方式结合起来。而且,最重要的是,你做错了,但只是纠正错误""不是答案。

您可以将两个参数放在一个列表中,然后在没有shell的情况下启动它,例如['./script.sh', variable]。这通常更好。使用shell意味着您必须处理引用,以及意外或恶意注入,并且可能干扰您的输入和输出,并增加性能成本。所以,如果你不需要它,就不要使用它。

或者您可以将两个参数放在一个字符串中,然后使用shell启动它,例如'./script.sh ' + variable

但是你不能把你的两个参数放在一个字符串中,然后将该字符串放在一个列表中。在某些情况下,它会发生作用,但这不是你可以依赖的东西。

在某些情况下,您可以使用带有shell的列表,*或不带shell的字符串,**但通常您不应该这样做,除非您知道自己在做什么,以及在任何情况下除非有特殊原因,否则你仍然不应该使用一个字符串列表。***


如果要使用参数列表,请执行以下操作:

subprocess.Popen(['./script.sh', variable], shell=False, …)

请注意,这是两个字符串的列表,而不是一个连接字符串的列表,以及shell=False


如果你想使用shell命令行,不要将命令行放在列表中,不要跳过参数之间的空格,并引用任何非静态参数,如下所示: / p>

subprocess.Popen('./script.sh ' + shlex.quote(variable), shell=True, …)

*在Windows上使用带有shell的列表永远不会有用;他们只是以一些未指明的方式组合起来。但是在Unix上,subprocess会有效地将'/bin/sh''-c'添加到您的列表中,并将其用作/bin/sh的arg列表,这可能比尝试引用shell更简单参数,至少可以说比用/bin/sh明确调用shell=False更简洁。

**在Unix上使用没有shell的字符串永远不会有用;只是试图找到一个程序,其名称是整个字符串,这将失败(除非你真的不走运)。但在Windows上,它可能很有用; subprocess尝试将您的参数组合成一个字符串,以便传递给CreateProcess,以便MSVCRT将它们解析回另一侧的相同参数列表,在某些边缘情况下它会&# 39;自己创建该字符串是必要的。

***基本上,你想要完全生成['/bin/sh', '-c', <command line>]

答案 3 :(得分:0)

只需在脚本名称后添加一个空格:

subprocess.Popen(['./script.sh ' + variable], shell=True,
    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)