似乎无法逃避脚本化 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
。)
好吧,我快死了。我知道我必须转义双引号等,但是我无法让下面的脚本 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
。)