2015-08-24 115 views
3

我试图从Python程序调用ssh,但它似乎忽略了参数。call()中忽略的参数

这是Python程序:参数,它们的值

#!/usr/bin/python 

from subprocess import Popen, PIPE, call 

vm_name = 'vmName with-space' 
vm_host = '[email protected]' 

def ssh_prefix_list(host=None): 
    if host: 
     # return ["ssh", "-v", "-v", "-v", host] 
     return ["scripts/ssh_wrapper", "-v", "-v", "-v", host] 
    else: 
     return [] 

def start(vm_name, vm_host=None): # vm_host defaults to None 
    print "vm_host = ", vm_host 
    vbm_args = ssh_prefix_list(vm_host) + ["VBoxManage", "startvm", vm_name] 
    print vbm_args 
    return call(vbm_args, shell=True) 

start(vm_name, vm_host) 

的包装印刷数量,并调用SSH。

#!/bin/bash 

echo Number of arguments: $# 
echo ssh arguments: "[email protected]" 
ssh "[email protected]" 

这是输出。

$ scripts/vm_test.py 
vm_host = [email protected] 
['scripts/ssh_wrapper', '-v', '-v', '-v', '[email protected]', 'VBoxManage', 'startvm', 'atp-systest Clone'] 
Number of arguments: 0 
ssh arguments: 
usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec] 
      [-D [bind_address:]port] [-e escape_char] [-F configfile] 
      [-i identity_file] [-L [bind_address:]port:host:hostport] 
      [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] 
      [-R [bind_address:]port:host:hostport] [-S ctl_path] 
      [-w local_tun[:remote_tun]] [[email protected]]hostname [command] 

这是关于Python 2.5的。

+0

半开玩笑的答案:尝试升级Python,也许问题会消失。 :-) – Kevin

+0

我们很乐意升级Python,但是我们使用的是Ubuntu的非常旧的版本,并且有很多依赖关系。我们正在努力。 –

回答

2

当您使用shell=True时,您需要传入一个字符串,而不是参数列表。尝试 -

return call(' '.join(vbm_args), shell=True) 

此外,你应该考虑构建从开始,而不是列表的字符串。

当你传递一个列表call()Popen()shell=True,只有列表中的第一个元素实际上是所谓的,那就是你看到调用0参数的包装的原因。

你也应该先尝试不使用shell=True,因为它是一个安全隐患,在documentation of subprocess作为明确指出 -

使用shell=True可能存在安全隐患。有关详细信息,请参阅Frequently Used Arguments下的警告。

+3

OP也可能首先考虑不使用'shell = True',因为这个命令看起来并不需要shell(它有一个shebang)。 – Kevin

+0

正确,并补充说,与文档链接。谢谢。 –

+1

删除'shell = True'解决了这个问题。谢谢。 –

0

我想这可能是它:

prefix_list = ssh_prefix_list(vm_host) 
prefix_list.append(["VBoxManage startvm %s" % vm_name]) 

但是我会强烈建议使用paramiko - 它使事情变得更加简单。

0

当您使用callshell=True,你需要传递一个字符串,而不是字符串数组。所以:

call("scripts/ssh_wrapper -v -v -v "+host+" VBoxManage startvm "+vmname)