sed 通过远程连接插入注释字符

sed 通过远程连接插入注释字符

我想在多行文件的任何位置搜索单词 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不会在您的起始目录中运行。同样,这可能永远不会影响到您,但这仍然是一个很好的通用做法。

相关内容