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

0 投票
1 回答
3133 浏览
提问于 2025-04-17 19:32

我正在尝试写一个函数,通过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 个回答

1

首先:

pipes.quotere.escape 这两个东西和本地运行的命令没有关系。它们只是用来处理字符串的;你之后怎么用它们就看你自己了。所以这两个,特别是 pipes.quote,都可以用来满足你的需求。

其次:

如果你想在远程主机上通过 ssh 运行命令 echo $(hostname),你不需要担心命令的转义问题,因为 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

我不太清楚你是否真的遇到了问题。

撰写回答