如何在Python中转义ssh引号的shell命令
我正在尝试写一个函数,通过ssh发出命令,并返回输出结果。
def remote(cmd):
escaped = escape(cmd)
return subprocess.Popen(escaped, ...).communicate()[0]
我遇到的问题是如何实现escape
这个函数。有没有适合Python 2.6的模块可以帮助我?谷歌显示有pipes.quote
和re.escape
,但它们似乎只适用于本地运行的命令。对于通过ssh传递的命令,转义的要求似乎要严格得多:
例如,在本地机器上,这样写是可以的:
echo $(hostname)
但传递给ssh时必须这样写:
ssh server "echo \$(hostname)"
另外,双引号在不同的上下文中可能会有不同的解释。对于字面上的引号,你需要这样处理:
ssh a4ipe511 "echo \\\"hello\\\""
要进行变量扩展时,也会使用双引号:
ssh a4ipe511 "echo \"\$(hostname)\""
正如你所看到的,传递给SSH的命令转义规则可能会变得相当复杂。因为这个函数会被任何人调用,我担心一些复杂的命令会导致函数返回错误的输出。
这是可以通过Python内置模块解决的吗,还是我需要自己实现转义功能?
1 个回答
1
首先:
pipes.quote
和 re.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
我不太清楚你是否真的遇到了问题。