sed 命令被认为是一个字符串 - 如何转义?

Sed command is considered a string - How to escape?

我有一个 sed 命令需要通过 SSH 执行。我在 Python 中使用 Paramiko 到 SSH 进行编码。连接有效,sed 命令也有效。我的问题是当我尝试合并它们时:我需要将 sed 用作 sudo(sudo 命令有效,我已经用另一个命令对其进行了测试)。这是我拥有的:

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""" + "\"")

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

sed: -e expression #1, char 11: unterminated `s' command

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

如果对您有帮助,请查看完整代码:

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"))

您的代码不太清楚。 绝对 不需要 运行 嵌套 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": "adddvariable" 替换(看起来是)JSON key/value hostname,替换旧值。

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