Help with if statement script

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
rothgar

Help with if statement script

Post by rothgar »

Hey everyone, I've hit a bit of a wall when trying to get a bash script working with an if statement. I was wondering if someone can have a look and try to help me out. Here is what I am trying to do.
I am running this script from my router (DD-WRT) to test if any known clients are awake on the network so that I can wake up the file server if they are on. I also need to test if the file server is awake on the network, if it is already on, then I obviously don't need to wake it up. I'm running this from cron but I don't think that is overly important as the if statement isn't passing/failing properly for me.

If the machines are on and the file server is off -> I need to WOL the file server
If the machines are on and the file server is on -> I can just exit
If the machines are off and the file server is on (or off) -> I can just exit (the file server will turn itself off when machines are not available)

The three known clients I'm looking for are 192.168.2.99, 192.168.2.50, and 192.168.2.60. The file server is 192.168.2.5.
With the code below, the WOL packet is always being sent (even if the file server is already on).

Code: Select all

if [ "`ping -c 3 -w 3 192.168.2.99 | wc -l`" -gt 6 -o "`ping -c
3 -w 3 192.168.2.50 | wc -l`" -gt 6 -o "`ping -c 3 -w 3 192.168.2.60 | wc -l`" -
gt 6 -a "`ping -c 3 -w 3 192.168.2.5 | wc -l`" -lt 6 ]; then /usr/sbin/wol -i 19
2.168.2.5 -p 7 00:0A:E4:89:B7:DE; fi
Basically by pinging the hosts I'm counting the lines returned by the ping command. When a machine is successfully ping'd there are 8 lines and unsuccessful there are 4.

But like I said, it's not working. Please help.
Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 1 time in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
User avatar
xenopeek
Level 25
Level 25
Posts: 29590
Joined: Wed Jul 06, 2011 3:58 am

Re: Help with if statement script

Post by xenopeek »

The if statement returns true if one of the machines is on; it doesn't get to checking the file server because it returns earlier if one of the machines is on (that is what -o, OR, does for you--something is already true, so no need to check the rest of the if statement :wink:).

Fix it by breaking it up into two if statements. The first if below returns true if at least one of the machines is on, the second if returns true if the file server is off. It should now do exactly as you specified. But perhaps the wol command is not correct if it isn't waking up the file server.

Code: Select all

if [ "`ping -c 3 -w 3 192.168.2.99 | wc -l`" -gt 6 -o \
     "`ping -c 3 -w 3 192.168.2.50 | wc -l`" -gt 6 -o \
     "`ping -c 3 -w 3 192.168.2.60 | wc -l`" -gt 6]; then \
        if [ "`ping -c 3 -w 3 192.168.2.5 | wc -l`" -lt 6 ]; then /usr/sbin/wol -i 192.168.2.5 -p 7 00:0A:E4:89:B7:DE; fi \
fi
You can remove the \ and newlines to turn it into one line again (but I didn't want to enter into the obfuscated BASH code contest :wink:).
Image
rothgar

Re: Help with if statement script

Post by rothgar »

Thanks! That works. I had a feeling I may need to nest ifs but I didn't realize the if would exit once something was true. I was hoping it would treat all the initial pings together and then move on to the file server automatically.

Sorry for the lack of line breaks, the router doesn't let me save scripts (read only file system) and the cron box doesn't handle line breaks well.

Thanks again!
mph426

Re: Help with if statement script

Post by mph426 »

I know that this may seem a little like overkill but, here's another way to look at it. It's written in a "C" style with the main program and a function. I try to code operations only once. That way if changes need to be made you only need to change one instance. Note that it uses fping instead of the standard ping. It's highly useful in situations like this. You can tune the output to exactly what you want to see.

Let me know if you have any questions.

BTW, If you want to find out where your script was failing, or for that matter what any script does / how it works, etc... type in /bin/bash -x ./script.sh (replace with your script.) This will show the script as it executes. If you use a different shell, such as ksh substitute accordingly.

IHTH

Code: Select all

#! /bin/bash
##########################################################################
# Vars
##########################################################################
server="192.168.2.5"
mac="00:0A:E4:89:B7:DE"
hosts="192.168.2.99 192.268.2.50 192.168.2.60"
##########################################################################
# Functions
##########################################################################
# getstat()  Get status of a remote host.
##########################################################################
getstat(){
  fping -qc 3 "$i" > /dev/null 2>&1
  status="$?"
}
##########################################################################
# Main
##########################################################################
# Note, the for statement only works because the $hosts variable has NO
# quotes. The for statement uses the standard field separator (a space).  
# If it were in quotes, it would be read as a single variable.
##########################################################################
for i in $hosts
do
  getstat "$i"
  if [ "$status" -ne 0 ]
  then
    getstat "$i"
    if [ "$status" -ne 0 ]
    then
      /usr/sbin/wol -i "$server" -p 7 "$mac"
    fi
  fi
done
MPH
Locked

Return to “Scripts & Bash”