0

I have the following script that defines an OLD and a NEW string. I want to replace the OLD with the NEW using sed over a remote connection. All the commands besides the sed appear to be working. I have tried adjusting punctuation and using pipes instead of forward slashes with sed to no avail. Doing the sed command from a command prompt works, but within the script, it does not. I would appreciate any input on this.

#!/bin/ksh

OLD="command\[Check_Memory_OS_10038\]=/opt/tools/nagitem/libexec/check_mem.pl -w 80,10 -c 90,25";export OLD
NEW="command\[Check_Memory_OS_10038\]=/opt/tools/nagitem/libexec/check_mem_ng.sh -w 80 -c 90";export NEW
DEST1="/opt/tools/nagitem/libexec/"
DEST2="/opt/tools/nagitem/nrdp/clients/nrds/"

for x in `cat /home/joe/nagios/hostlist`
do
SSH_STATUS=$(ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $USER@$x "pwd" >/dev/null)
  if [[ $? = "0" ]];then
    scp -p /home/joe/nagios/check_mem_ng.sh $x:/tmp
    ssh -o "StrictHostKeyChecking no" $x "sudo /usr/localcw/bin/eksh -c '/bin/cp /tmp/check_mem_ng.sh $DEST1;chown nagitem:nagitem $DEST1/check_mem_ng.sh;cd $DEST2; /bin/sed -i -e 's/'$OLD'/'$NEW'/g' /opt/tools/nagitem/nrdp/clients/nrds/nrds.cfg '"
else
   echo "Cannot connect to $x" >> badhosts
fi
done

Error received is: /bin/sed: -e expression #1, char 39: unknown option to `s'

3
  • 1
    Note how your strings contain /, which is the default delimiter in the s/// command. Either escape them in your strings, or use another delimiter character (s@@@?).
    – Kusalananda
    Mar 2, 2021 at 21:53
  • I tried the following to use pipes in the sed, ending up with more errors. ssh -o "StrictHostKeyChecking no" $x "sudo /usr/localcw/bin/eksh -c '/bin/cp /tmp/check_mem_ng.sh $DEST1;chown nagitem:nagitem $DEST1/check_mem_ng.sh;cd $DEST 2; /bin/sed -i -e 's|'$OLD'|'$NEW'|g' /opt/tools/nagitem/nrdp/clients/nrds/nrds.cfg '"
    – jackcsprat
    Mar 2, 2021 at 22:36
  • When I try to escape my strings, I get this error: /bin/sed: -e expression #1, char 0: no previous regular expression
    – jackcsprat
    Mar 2, 2021 at 22:43

2 Answers 2

0

This code of yours required an overhaul in a couple of places.

  • The initializations of environment vars $OLD n $NEW to use no escaping as they get backslash ed downstream, lest they be double escaped.
  • Escape $OLD var so that it becomes saf e for plug in on the LHS of a sed substitute command.
  • Similarly, Escape the $NEW var for use on RHS of the substitute command.
  • The sed command is using single quotes within single quotes under the overall umbrella of double quotes , so they were escaped taking care to escape any single quotes within new or old var values too.
#!/bin/ksh

OLD="command[Check_Memory_OS_10038]=/opt/tools/nagitem/libexec/check_mem.pl -w 80,10 -c 90,25";export OLD
NEW="command[Check_Memory_OS_10038]=/opt/tools/nagitem/libexec/check_mem_ng.sh -w 80 -c 90";export NEW
DEST1="/opt/tools/nagitem/libexec/"
DEST2="/opt/tools/nagitem/nrdp/clients/nrds/"

#--------------------
# escape variables
eOLD=$(printf '%s\n' "$OLD" | sed -e 's:[][\/^$.*]:\\&:g' -e "s:':&\\&&:g")
eNEW=$(printf '%s\n' "$NEW" | sed -e 's:[\/&]:\\&:g' -e "s:':&\\&&:g")
#--------------------

for x in `cat /home/joe/nagios/hostlist`
do
SSH_STATUS=$(ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $USER@$x "pwd" >/dev/null)
  if [[ $? = "0" ]];then
    scp -p /home/joe/nagios/check_mem_ng.sh $x:/tmp
    ssh -o "StrictHostKeyChecking no" $x "sudo /usr/localcw/bin/eksh -c '/bin/cp /tmp/check_mem_ng.sh $DEST1;chown nagitem:nagitem $DEST1/check_mem_ng.sh;cd $DEST2; /bin/sed -i -e '\\''s/$eOLD/$eNEW/g'\\'' /opt/tools/nagitem/nrdp/clients/nrds/nrds.cfg'"
else
   echo "Cannot connect to $x" >> badhosts
fi
done
5
  • Thanks for the rewrite, but I get the following errors. When the script first executes: sed: -e expression #1, char 17: unterminated `s' command After the script has fully executed and has exited, the following error appears: /bin/sed: -e expression #1, char 0: no previous regular expression
    – jackcsprat
    Mar 3, 2021 at 4:46
  • Rather than trying to do everything on the remote host, just cat the remote file and work on it locally (or scp it over here). Then transfer it back. This makes quoting easier.
    – Kusalananda
    Mar 3, 2021 at 7:48
  • @jackcsprat can you place an echo before thevssh command and share the output. Also copy paste from my code only as I made extensive rewrite.
    – guest_7
    Mar 3, 2021 at 9:26
  • @guest_7 At exit of script: check_mem_ng.sh 100% 6294 6.2KB/s 00:00 ssh -o StrictHostKeyChecking no myserver sudo /usr/localcw/bin/eksh -c '/bin/cp /tmp/check_mem_ng.sh /opt/tools/nagitem/libexec/;chown nagitem:nagitem /opt/tools/nagitem/libexec//check_mem_ng.sh;cd /opt/tools/nagitem/nrdp/clients/nrds/; /bin/sed -i -e '\''s//command[[]Check_Memory_OS_10038[]]=\/opt\/tools\/nagitem\/libexec\/check_mem_ng.sh -w 80 -c 90/g'\'' /opt/tools/nagitem/nrdp/clients/nrds/nrds.cfg '
    – jackcsprat
    Mar 3, 2021 at 15:43
  • Thanks for sharing the data. It enabled me to get to the issue. Now copy again and give it a spin. It will fly now.
    – guest_7
    Mar 3, 2021 at 17:10
0

You quote your eksh parameter with single quotes '. Inside single quotes, there is no possibility to expand special characters. So your $DEST and other variables are not expanded, leaving some weird residuals.

1
  • Note that the eksh -c invocation itself is within double quotes. The shell would therefore expand the variables.
    – Kusalananda
    Mar 3, 2021 at 7:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.