使用Python和subprocces.call执行脚本的问题仍然适用于Bash

时间:2010-05-25 22:16:35

标签: python subprocess xen bash

我第一次在这里要求一些帮助,因为我更像是一个ServerFault人员。

我正在使用Python编写一些脚本,到目前为止我一直很喜欢这种语言但是我遇到了一个小问题,这使我的脚本无法工作。

以下是相关代码行:

subprocess.call('xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd',shell=True)

我和os.popen尝试过同样的事情。所有变量都已正确设置。

当我在常规Linux shell中执行相关命令时,它运行得很好但是当我使用Python脚本执行它时,我会遇到奇怪的错误。我甚至用print函数替换了subprocess.call(),以确保我使用命令的确切输出。

我去研究我的shell的环境变量,但它们几乎一样......我会发布我得到的错误,但我不确定它与我的问题有关。

  

在/usr/share/perl5/Config/IniFiles.pm第614行使用未初始化的值$ lines [0]替换(s ///)。   在/usr/share/perl5/Config/IniFiles.pm第628行使用模式匹配(m //)中未初始化的值$ _。

我不是Python专家,所以我很可能在这里遗漏了一些东西。

提前感谢您的帮助,

安托


修改

根据miax的建议,我停止使用shell = True。相反,我查看了subprocess的Python文档,并使用了以下代码:

cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
args = shlex.split(cmd)
subprocess.call(args)

可悲的是,它没有改变任何东西......


EDIT2

我使用了miax给出的提示,但我仍然遇到上述错误......这是我使用过的代码。

cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']
subprocess.call(cmd)

这真的很奇怪...当我在常规shell中运行时,确切的命令工作正常......

4 个答案:

答案 0 :(得分:2)

您(在大多数情况下)不希望将子进程与shell=True一起使用。 将命令列表传递给命令。那是

  • 更安全:想象一下,用户设法将foo; rm -rf /; echo作为一些值传递。
  • 更可靠:想象一下,其中一个字符串包含$或其他内容 - 它将由shell扩展,并由该环境变量的内容替换。

在不知道您的代码和xen-create-image的情况下,我认为这是您遇到问题的原因。

PS:请务必查看命令的退出代码是否为零,如果不是,则执行相应的操作。 (如果您确定它将始终为零,请使用check_call,如果不是则会引发;这样,如果失败,您至少会有一个已定义的行为。)

答案 1 :(得分:0)

在您失败的 Edit2 示例中,您认为您正在向xen-create-image提供以下选项:

  • --hostname
  • --memory
  • --partitions=...

...但您确实指定了以下选项:

  • --hostname 空间
  • 空间 --memory 空间
  • 空间 --partitions=...

你有这一行:

cmd = ['xen-create-image', '--hostname ', nom, ' --memory ', memory, ' --partitions=/root/scripts/part.tmp', ' --ip ', ip, ' --netmask ', netmask, ' --gateway ', gateway, ' --passwd']

但是你需要拿出额外的空格:

cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']

答案 2 :(得分:0)

您需要print您正在使用的命令:

cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
print "COMMAND:", cmd

然后将命令粘贴到shell中以确保它完全相同。

答案 3 :(得分:0)

xen-create-image脚本是否以hashbang开头?也就是说,第一行是

#!/bin/sh

?这是一件值得检查的事情。另一个是您可以尝试将命令称为:

cmd = ['/bin/sh', '-c', 'xen-create-image --hostname %s --memory %s --partitions=/root/scripts/part.tmp --ip %s --netmask %s --gateway %s --passwd' % (nom, memory, ip, netmask, gateway)]
subprocess.call(cmd, shell=False)

您可能希望打印cmd以验证这是您打算运行的命令(即检查替换)。