python子进程不能与ssh命令一起使用

时间:2017-09-27 15:12:51

标签: python ssh subprocess

在我的桌面上,以下shell命令列出远程服务器上根/aa/*/bb/的目录

ssh my_server 'echo /aa/*/bb/'

但是,当我从python子进程调用它时,它报告错误

  

CalledProcessError:Command' [' ssh',' my_server',' echo / aa / * / bb /']'返回非零退出状态255

,代码在这里

subprocess.check_output(['ssh', 'my_server', 'echo /aa/*/bb/'], shell=True)

但是,如果我登录到远程服务器,并运行

subprocess.check_output('echo /aa/*/bb/', shell=True)

有效。

我做错了什么?非常感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

您的shell=True会阻止传递参数。那是因为:

subprocess.check_output(['ssh', 'my_server', 'echo /*/'], shell=True)

...运行代码:

# /- from shell=True
# |  ^  /- your first argument, becomes the script "sh -c" runs
# |  |  |   /- your second argument, becomes $0 to that script
# |  |  |   |         /- your third argument, becomes $1 to that script
# |  |  |   |         |
  sh -c ssh my_server 'echo /*/'

所以,你传递了你的shell脚本(只是确切的字符串ssh)参数$ 0和$ 1,但它根本没有读取它们

如果您希望将其与shell=True一起使用,则可以将其更改为:

#                        script      $0   $1           $2
subprocess.check_output(['ssh "$@"', '_', 'my_server', 'echo /*/'], shell=True)

但更好的是将这个论点抛弃:

subprocess.check_output(['ssh', 'my_server', 'echo /*/'])

答案 1 :(得分:1)

我建议您根据文档中的此部分将参数更改为字符串而不是列表:

  

在带有shell=True的Unix上,shell默认为/ bin / sh。如果args是一个字符串,则该字符串指定要通过shell执行的命令。这意味着字符串的格式必须与在shell提示符下输入的格式完全相同。如果args是一个序列,则第一个项指定命令字符串,并且任何其他项将被视为shell本身的附加参数。也就是说,Popen相当于:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

这将手动执行命令(在子shell中):

subprocess.check_output('ssh my_server "echo /*/"', shell=True)

另一方面,当使用序列作为参数时,每个项目需要是列表中的单个项目,就像那样

subprocess.check_output(['ssh', 'my_server', 'echo', '/aa/*/bb/'], shell=True)
相关问题