Sed命令被认为是一个字符串 - 如何逃脱?

时间:2018-06-12 14:01:27

标签: python-2.7 ssh sed paramiko

我有一个需要通过SSH执行的sed命令。我使用Paramiko进行SSH编码。连接工作和sed命令也是如此。我的问题是当我尝试合并它们时:我需要使用sed作为sudo(sudo命令工作,我用另一个命令测试它)。这就是我所拥有的:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
    hostname=server_address,
    username=server_username,
    key_filename=server_key_file
)
session = ssh.get_transport().open_session()
session.set_combine_stderr(True)
session.get_pty() 
session.exec_command("sudo bash -c \"" + """sudo sed -i "s/\"hostname\":"  *"\".*\"/\"hostname\":"  *"\"adddvariable\"/" /home/frappe/frappe-bench/sites/test-dev.site1.local/site_config.json""" + "\"")
stdin = session.makefile('wb', -1)
stdout = session.makefile('rb', -1)
stdin.flush()
frappe.msgprint(_(stdout.read().decode("utf-8"))) # same as print(stdout.read().decode("utf-8"))

问题是当这个命令运行时,sed被认为是'未完成',我得到:

  

sed:-e表达式#1,字符11:未终止的's'命令

我认为这可能是由于sed命令中的空格?我不知道如何解决这个问题。我是Python,Paramiko和SSH的新手。有人知道如何解决这个问题吗?

如果有帮助,这是完整的代码:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
    <ribbon startFromScratch="false">
        <tabs>
            <tab id="customTab" label="Custom Layout" insertBeforeMso="TabHome">
            </tab>
            <tab idMso="TabHome" visible="false" />
                <tab idMso="TabInsert" visible="false" />
                <tab idMso="TabFormulas" visible="false" />
                <tab idMso="TabData" visible="false" />
                <tab idMso="TabReview" visible="false" />
                <tab idMso="TabView" visible="false" />
                <tab idMso="TabDeveloper" visible="false" />
            <tab idMso="TabPageLayout" visible="false"/>
        </tabs>
    </ribbon>
</customUI>

1 个答案:

答案 0 :(得分:1)

你的代码还不清楚。应该肯定不需要运行嵌套的sudo命令,对于单个命令,将它包装在sudo bash -c中什么都不会实现,并引入了一个多余的过程和显着增加的安全表面,以及重要的引用问题。

通过在sed脚本周围使用单引号而不是双引号,以及摆脱额外的sudo bash -c,可能最容易解决您的直接问题。

session.exec_command("""sudo sed -i 's/"hostname":  *"[^"]*"/"hostname":  "adddvariable"/' /home/frappe/frappe-bench/sites/test-dev.site1.local/site_config.json""")

我不完全确定我能猜出sed命令应该真正实现的目标。这个用hostname替换(似乎是)JSON键/值"hostname": "adddvariable",替换旧值。

sed -i的参数应该是一个字符串;一对单引号可防止shell分解并标记或以其他方式更改单引号之间的文本。如果你没有特别需要shell在字符串中执行变量插值和/或命令替换,你基本上应该总是使用单引号。