【问题标题】:How to escape ssh quoted shell commands in Python如何在 Python 中转义 ssh 引用的 shell 命令
【发布时间】:2013-03-18 19:14:57
【问题描述】:

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

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 模块解决的问题,还是我需要自己实现转义?

【问题讨论】:

    标签: python shell ssh escaping


    【解决方案1】:

    第一:

    pipes.quotere.escape 与本地运行的命令无关。他们只是转换一个字符串;在那之后你用它做什么是你的事。所以任何一个——尤其是pipes.quote——都适合你想要的。

    第二:

    如果您想使用ssh 在远程主机上运行命令echo $(hostname),则无需担心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
    

    我不清楚你是否真的有问题。

    【讨论】:

    • 谢谢,您的解决方案运行良好。看起来像使用 shell=False 作为序列传递一样,解决了这个问题。虽然我认为对于任何想要通过传递字符串参数并使用 shell=True 来解决此问题的人来说,这可能仍然是一个问题。
    猜你喜欢
    • 2012-04-19
    • 2021-10-09
    • 2014-08-21
    • 2016-08-25
    • 2011-04-25
    • 1970-01-01
    • 2013-07-08
    • 2013-03-12
    • 2013-12-28
    相关资源
    最近更新 更多