2013-11-22 52 views
6

我有一个脚本通过subprocess.Popen模块调用另一个python脚本。但因为我有存储在变量(一个或多个)将变量传递给子进程.Popen

servers[server]['address'] 
servers[server]['port'] 
servers[server]['pass'] 

论点我无法执行的命令

p = subprocess.Popen(["python mytool.py -a ", servers[server]['address'], "-x", servers[server]['port'], "-p", servers[server]['pass'], "some additional command"], shell=True, stdout=subprocess.PIPE) 

解决方法:

我得到了它的@wilberforce &梳理工作@ ciphor的答案,但受了一点修改

command = "python mytool.py -a %s -x %s -p %s some additional command" % (servers[server]['address'], servers[server]['port'], servers[server]['pass']) 
p = subprocess.Popen(command , shell=True, stdout=subprocess.PIPE) 

如果我在双引号中添加了多个变量,它会停止工作,它可能需要最大“2”变量,并且我添加更多的变量。

感谢大家回答!

+1

使用这些变量来构建一个字符串即命令,或将它们作为参数列表传递。 – beroe

回答

5

删除shell=TrueThe arguments to Popen() are treated differently on Unix if shell=True

import sys 
from subprocess import Popen, PIPE 

# populate list of arguments 
args = ["mytool.py"] 
for opt, optname in zip("-a -x -p".split(), "address port pass".split()): 
    args.extend([opt, str(servers[server][optname])]) 
args.extend("some additional command".split()) 

# run script 
p = Popen([sys.executable or 'python'] + args, stdout=PIPE) 
# use p.stdout here... 
p.stdout.close() 
p.wait() 

注意,通过shell=True用于与外部输入的命令是一个安全危险,如通过一个警告in the docs说明。

2

当你调用subprocess.Popen你可以传递一个字符串或要运行的命令列表。如果你通过一个列表,这些项目应该以特定的方式分割。

在你的情况,你需要拆分它是这样的:

command = ["python", "mytool.py", "-a", servers[server]['address'], 
      "-x", servers[server]['port'], 
      "-p", servers[server]['pass'], 
      "some", "additional", "command"] 
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) 

这是因为如果你在列表中通过,Popen假设你已经在命令行分割成字(该值即会最终在sys.argv),所以它不需要。

你打电话的方式,它会尝试运行一个名为“蟒蛇mytool.py -a”二元,这是不是你的意思。

解决它的另一种方法是将所有单词连接到一个字符串中(然后Popen将分裂 - 请参阅subprocess.list2cmdline)。但是,如果可能的话,最好使用列表版本 - 它可以更简单地控制命令行的分割方式(例如,参数中有空格或引号),而不必乱用引号字符。在第一Popen参数str

p = subprocess.Popen("python mytool.py -a " + servers[server]['address'] + " -x " + servers[server]['port'] + " -p " + servers[server]['pass'] + " some additional command", shell=True, stdout=subprocess.PIPE) 
+0

我用来存储输出的变量,但是在打印时它是空的(我猜它没有被执行)。 – GaNi

+0

我认为你的意思是,当你从p。标准输出,没有输出?那将是因为命令没有运行。 – babbageclunk

+0

实际上,shell = True可能会让这里的水变得浑浊 - 除非你使用globbing(例如展开文件列表),否则最好关闭它。 – babbageclunk

1

你应该串联命令整个字符串。将其替换为list。下面的代码可以工作:

address = servers[server]['address'] 
port = servers[server]['port'] 
pass = servers[server]['pass'] 

command = "python mytool.py -a %s -x %d -p %s some additional command" % (address, port, pass) 
p = subprocess.Popen(command.split(), shell=True, stdout=subprocess.PIPE) 
#     ^^^^^^^^^^^^^^^ 

此外,您可以用shell玩,因为它的系统依赖的参数。

+0

我有输出保存到变量,但没有输出或正在执行的脚本的跟踪。可能是直接错误输出来检查它? – GaNi

+0

添加“stderr = subprocess.PIPE”也 – ciphor

1

您的问题:

+0

有类似的问题,但我现在解决了它。谢谢 :) – GaNi