似乎无法逃避脚本化bash命令。每次输出错误/不正确
好吧,这简直要了我的命。我知道我必须转义双引号等,但是我无法使下面的脚本化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/
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'