如何在Python中转义ssh引用的shell命令

时间:2013-03-18 19:14:57

标签: python shell ssh escaping

我正在尝试编写一个函数,它将通过带有Popen的ssh发出命令并返回输出。

def remote(cmd):
    escaped = escape(cmd)
    return subprocess.Popen(escaped, ...).communicate()[0]

我的麻烦是如何实现escape功能。是否有一个Python模块(2.6)有这个帮手?谷歌显示有pipes.quotere.escape,但它们似乎只适用于本地运行的命令。随着命令传递给ssh,似乎逃避需要更加严格:

例如在本地计算机上,这没关系:

echo $(hostname)

传递给ssh时必须是:

ssh server "echo \$(hostname)"

此外,双引号可以根据上下文以不同方式解释。对于文字引号,您需要以下内容:

ssh a4ipe511 "echo \\\"hello\\\""

要进行变量扩展,还会使用双引号:

ssh a4ipe511 "echo \"\$(hostname)\""

正如您所看到的,转义为SSH的命令的规则可能变得非常复杂。由于任何人都会调用此函数,我担心一些复杂的命令会导致函数返回错误的输出。

这是可以通过内置Python模块解决的问题还是我需要自己实现转义?

1 个答案:

答案 0 :(得分:1)

首先:

pipes.quotere.escape与本地运行的命令无关。他们只是变换一个字符串;在那之后你用它做什么就是你的事。所以,特别是pipes.quote - 适合你想要的东西。

第二

如果要使用echo $(hostname)在远程主机上运行命令ssh,则无需担心shell转义,因为subprocess.Popen未将命令传递给shell默认情况下。所以,例如,这很好用:

>>> import subprocess
>>> subprocess.call([ 'ssh', 'localhost', 'echo $(hostname)'])
myhost.example.com
0

双引号也可以按预期工作:

>>> subprocess.call([ 'ssh', 'localhost', 'echo "one   two"; echo three'])
one   two
three
0

我不清楚你确实遇到了问题。