![sed 通过远程连接插入注释字符](https://linux22.com/image/1561399/sed%20%E9%80%9A%E8%BF%87%E8%BF%9C%E7%A8%8B%E8%BF%9E%E6%8E%A5%E6%8F%92%E5%85%A5%E6%B3%A8%E9%87%8A%E5%AD%97%E7%AC%A6.png)
我想在多行文件的任何位置搜索单词 Logmon 的出现位置。对于找到匹配项的每一行,在行开头插入一个 #。我可以使用以下方法实现此目的:
sed -i '/Logmon/ s/^/#/' nrds.cfg
上述操作实现了我的目标,但是,我在执行远程服务器列表时遇到了问题。以下是我目前所得到的结果。
#!/bin/ksh
DEST="/usr/local/nrdp/clients/nrds/"
for x in `cat /home/jack/hostlist`
do
SSH_STATUS=$(ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $USER@$x "pwd" >/dev/null)
if [[ $? = "0" ]];then
ssh -o "StrictHostKeyChecking no" $x "sudo /usr/localcw/bin/eksh -c 'cd $DEST; sed -i "/Logmon/ s/^/#/" nrds.cfg'"
else
echo "Cannot connect to $x" >> badhosts
fi
done
以上返回以下错误: sed: -e 表达式 #1,字符 8:缺少命令
我怀疑问题出在我的引用上,或者我需要转义一个或多个正斜杠。我尝试了很多方法,但似乎总是得到上述相同的错误。
答案1
引用问题。以下是发生的情况:
"sudo /usr/localcw/bin/eksh -c 'cd $DEST; sed -i "/Logmon/ s/^/#/" nrds.cfg'"
^ double quoting starts ends here^ starts anew^ ends^
因此,sshd
在远程端运行:
sudo /usr/localcw/bin/eksh -c 'cd $DEST; sed -i /Logmon/ s/^/#/ nrds.cfg'
eksh
得到:
cd $DEST; sed -i /Logmon/ s/^/#/ nrds.cfg
所以现在表达式 #1sed
就是/Logmon/
。要解决这个问题,你应该转义应该到达远端的双引号,如下所示:
"sudo /usr/localcw/bin/eksh -c 'cd \"$DEST\" && sed -i \"/Logmon/ s/^/#/\" nrds.cfg'"
还有一些额外的改进:
- 我还引用了
$DEST
以确保您进入cd "<local value of $DEST>"
远程端而不是cd <local value of $DEST>
。当值为 时,这对您的特定情况没有任何影响/usr/local/nrdp/clients/nrds/
;但是如果您将此路径更改为 eg,/foo/bar baz/
那么它将破坏您的“无引号”cd
调用。 &&
确保sed
仅在成功时运行cd
(我不确定它是否在 中有效eksh
,无论它是什么;但它在许多 shell 中有效)。如果由于某种原因cd
失败,则sed
不会在您的起始目录中运行。同样,这可能永远不会影响到您,但这仍然是一个很好的通用做法。