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

似乎无法逃避脚本化bash命令。每次输出错误/不正确,bash,escaping,Bash,Escaping,好吧,这简直要了我的命。我知道我必须转义双引号等,但是我无法使下面的脚本化bash命令正常工作 在远程服务器上,以下命令按预期工作: sed 's|EX_ROOT=/root/$SERVER|EX_ROOT="/root/$SERVER"|g' /etc/example/config.conf 结果:EX_ROOT=“/ROOT/$SERVER” (这就是费用D) 但是,从其他服务器远程运行命令时,如下所示: ssh root@$HWNODEIP "sed 's|EX_ROOT=/root/

好吧,这简直要了我的命。我知道我必须转义双引号等,但是我无法使下面的脚本化bash命令正常工作

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

sed 's|EX_ROOT=/root/$SERVER|EX_ROOT="/root/$SERVER"|g'  /etc/example/config.conf
结果:EX_ROOT=“/ROOT/$SERVER”

(这就是费用D)

但是,从其他服务器远程运行命令时,如下所示:

ssh root@$HWNODEIP "sed 's|EX_ROOT=/root/$SERVER|EX_ROOT="/root/$SERVER"|g' /etc/example/config.conf"
不添加双引号。所以我记得我必须避开双引号。但在这里我遇到了一堵墙。无论我尝试什么,我都没有得到预期的结果

例1: 给出:EX_ROOT=“/ROOT/”$SERVER

($SERVER不在引号内)

例2: 给出:EX_ROOT=“/ROOT/$SERVER”$SERVER

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

预期/预期结果:
我不知道我在这里做错了什么。我知道我很接近,但真的不知道。我尝试了一些其他的事情,比如使用更多的引号,尝试逃避更多,但都没有结果,现在我没有主意了…

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

你需要逃离他们。示例2很接近,但您忘记在正则表达式中转义美元符号,因此在未设置的局部变量
SERVER
扩展为空字符串后运行
sed's | EX_ROOT=/ROOT/| EXROOT=“/ROOT/$SERVER”

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
不必从标准输入读取要编辑的数据,因此它可以从标准输入读取脚本,每行一个命令。语法基本上与
sed
相同。不过,现在需要的转义要少得多,因为脚本不会暴露在远程端的shell中。(如果
wq
命令看起来很熟悉,那是因为
vi
基于
ex
,后者基于
ed

旁注:
sed-E's |(ex_ROOT=)(/ROOT/$SERVER)|\1“\2”| g'
只有一个反冲。。。。啊!!我以为我以前试过,但显然我没有。否则我就不会发布这个了。谢谢你解释得这么详细。在不久的将来,我会记住这一点。感谢您提供详细的答案!非常感谢。您修改
config.conf
的最终目标是否到位?您希望改用
ed
,它从标准输入而不是命令行参数读取脚本。然后您可以简单地编写
printf的|…| g\nwq\n'| ssh$host'ed/etc/example/config.conf'
,大大简化引用。是的,但是我使用了-I?多亏了你的解释,我试过了,现在效果不错。我觉得
-I
有点毫无意义
sed
是基于
ed
的流编辑器,旨在方便编辑任意文本流,而不仅仅是文件。如果要编辑文件,请返回
ed
:)
EX_ROOT="/root/$SERVER"
ssh root@$HWNODEIP "sed 's|EX_ROOT=/root/\$SERVER|EX_ROOT=\"/root/\$SERVER\"|g' /etc/example/config.conf"
                                         ^
                                         |
                                 backslash here
printf 's|EX_ROOT=$SERVER|EX_ROOT="$SERVER"|g\nwq\n' |
    ssh root@$HWNODEIP 'ed /etc/example/config.conf'