似乎无法逃避脚本化 bash 命令。每次错误/不正确的输出

Cannot seem to escape a scripted bash command. Every time wrong / incorrect output

好吧,我快死了。我知道我必须转义双引号等,但是我无法让下面的脚本 bash 命令正常工作。

在远程服务器上,以下命令按预期工作:

sed 's|EX_ROOT=/root/$SERVER|EX_ROOT="/root/$SERVER"|g'  /etc/example/config.conf

结果:EX_ROOT="/root/$SERVER"

(这是预期的)

然而,当 运行 从不同的服务器远程执行命令时,如下所示:

ssh root@$HWNODEIP "sed 's|EX_ROOT=/root/$SERVER|EX_ROOT="/root/$SERVER"|g' /etc/example/config.conf"

不添加双引号。所以我记得我必须转义双引号。不过我这里运行撞墙了。无论我尝试什么,我都没有得到预期的结果。

示例 1:

ssh root@$HWNODEIP "sed 's|EX_ROOT=/root/$SERVER|EX_ROOT="\""/root/$SERVER"\""|g' /etc/example/config.conf"

给出:EX_ROOT="/root/"$SERVER

($SERVER 不在引号内)

示例 2:

ssh root@$HWNODEIP "sed 's|EX_ROOT=/root/$SERVER|EX_ROOT=\"/root/$SERVER\"|g' /etc/example/config.conf"

给出:EX_ROOT="/root/$SERVER"$SERVER

(接近但仍不是预期结果)

预期/期望的结果:

EX_ROOT="/root/$SERVER"

我不知道我做错了什么。我知道我很接近,但真的不知道。我尝试了一些其他的事情,比如使用更多的引号并试图转义更多,但都没有结果,现在我没有想法了......

您的第一次尝试没有将双引号发送到远程服务器;他们在本地关闭并重新打开您的双引号字符串。

你需要逃离他们。您的示例 2 是 close,但您忘记在正则表达式中转义美元符号,因此您在未设置的局部变量 [=] 之后结束了 运行 sed 's|EX_ROOT=/root/|EXROOT="/root/$SERVER"' 13=] 扩展为空字符串。

ssh root@$HWNODEIP "sed 's|EX_ROOT=/root/$SERVER|EX_ROOT=\"/root/$SERVER\"|g' /etc/example/config.conf"
                                         ^
                                         |
                                 backslash here

不过,要就地编辑文件,请使用 ed 而不是非标准 sed 扩展名 -i.

printf 's|EX_ROOT=$SERVER|EX_ROOT="$SERVER"|g\nwq\n' |
    ssh root@$HWNODEIP 'ed /etc/example/config.conf'

由于 ed 不必从标准输入读取数据进行编辑,它可以从标准输入读取 script,每行一个命令。语法与 sed 基本相同。不过,现在您需要的转义要少得多,因为脚本不会暴露给远程端的 shell。 (如果 wq 命令看起来很眼熟,那是因为 vi 基于 ex,而 ex 基于 ed。)