0

I have multiple servers and want to set up a periodic check so that trapserver(s) has correct trapaddress(es). trapserver 1 as 10.10.10.1 and trapserver2 as 10.10.10.2. However the below script does not see $trapaddress value of 10.10.10.x with "10.10.10.x" as equal?

Not sure where I am going wrong?

Many thanks

#!/bin/bash
for LINE in $( cat /home/username/serverslist.txt )
do
SERVER=`(echo $LINE | awk -F : '{ print $1 }')`

echo " "

echo $SERVER
traphost=$( ssh $SERVER -t sudo cat /etc/traphost.txt )
trapaddress=$( ssh $SERVER -t sudo cat /etc/trapaddress.txt )
echo -e " Traphost is $traphost \n Trapaddress is $trapaddress"

if [ $traphost = "trapserver1" ] && [ $trapaddress= "10.10.10.1" ] || [ $traphost = "trapserver2" ] && [ $trapaddress= "10.10.10.2" ] ;
       then
        echo "server is happy."
       else
        echo  " $servername server has incorrect $trapaddress ."
fi
done
ilkkachu
  • 138,973
  • There are lots of things to comment here on but, taking just one, add a space before = in the tests. In other words, replace [ $trapaddress= "10.10.10.1" ] with [ "$trapaddress" = "10.10.10.1" ] – John1024 Feb 19 '19 at 21:50
  • 1
    Also, in general, whenever you have a shell script error, a good first step is to cut and paste your code into shellcheck.net and correct the errors (important) and warnings (might be important) that it identifies. If you have trouble understanding its messages, then come here and ask. – John1024 Feb 19 '19 at 21:51

1 Answers1

1

First, I assume the lack of space before the = in [ $trapaddress= "10.10.10.1" ] is a typo. If it weren't you'd immediately get an error from [.

Second, you have a problem in the relation between the && and || operators. In the shell, they are processed left to right, so your condition doesn't do what you want it to do. In fact, this:

if cond1 && cond2 || cond3 && cond4; then ... 

is more like this:

if ((cond1 && cond2) || cond3) && cond4; then ... 

Notably, it requires cond4 to be true. What you want is either

if ( ... && ...) || ( ... && ... ); then ...

or

if [[ ... && ... || ... && ... ]]; then ...

(Within [[ .. ]] they do have the usual relative precedence.)

If you want, you could concatenate the variables to make the comparison easier, assuming they never contain e.g. a slash:

if [[ "$traphost/$trapaddress" = "trapserver1/10.10.10.1" ||
      "$traphost/$trapaddress" = "trapserver2/10.10.10.2" ]]; then ...

Note that you want to quote the variables to avoid word splitting, see When is double-quoting necessary?

ilkkachu
  • 138,973
  • I have changed to this however I am experiencing the same issue. The problem is that although the value of $trapaddress echoing as 10.10.10.1 but if condition does not match it with "10.10.10.1", which is really strange and goes to else condition, instead of then.

    if [[ "$traphost/$trapaddress" = "trapserver1/10.10.10.1" || "$traphost/$trapaddress" = "trapserver2/10.10.10.2" ]]; then ...

    – Syed Mazhar Feb 19 '19 at 22:25
  • @SyedMazhar, ah, right. Check that you don't have any traiiling whitespace or such in there. Put something like printf "host <%s> addr <%s>\n" "$traphost" "$trapaddress" there in the script to see that. Or even look at the file itself to see any invisible characters. od -c /etc/trapaddress.txt or such should do. If there's anything to see edit your question to add it in, the comments don't really lend well for presenting code and output like that – ilkkachu Feb 19 '19 at 22:26
  • True, there seems to be issue with line 1 changed.. is there a way I can transfer $IP value without just the IP address and remove any whitespaces? will look further. thanks output was

    1c1

    < 10.10.10.1

    10.10.10.1

    – Syed Mazhar Feb 19 '19 at 22:38
  • @SyedMazhar, there are probably better ways, but you already have used awk, so you could use it here, too. awk '{ print $1 }' /etc/trapaddress.txt would print just the first field, removing extra whitespace. Or tr -dc '0-9.' /etc/trapaddress.txt, it would remove anything but digits and dots. – ilkkachu Feb 19 '19 at 22:45
  • tr -dc '0-9.' worked perfectly , you are a star. Many thanks Sir.

    awk '{print $3 }' | tr -dc '0-9.'

    – Syed Mazhar Feb 19 '19 at 22:56