Trying to count # of times an 'if' statement is true in a loop.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Trying to count # of times an 'if' statement is true in a loop.
I just have no idea how to do what I'm looking for here. I have a simple script (see below) that pings a list of sites from a separate text file. I want to count how many times the pings fail -per site-. I understand how to count total failures, but I have no clue how to keep the count separate for each site.
Bash script
Code:
#!/bin/bash
for i in {1..3600}
do
clear ; echo -e "Interval $i"
while IFS=, read name ip
do
ping -c 1 $ip >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo -e "\e[31;1mName: $name\t$ip \t- down.\e[0m\tCount: ___"
else
echo -e "\e[32;1mName: $name\t$ip \t- up!\e[0m\tCount: ___"
fi
done < ~/monitor.txt
# 30 sec Countdown Timer
for i in {30..1};do echo -ne "\r$i" && sleep 1;echo -ne "\r "; done
done
Assuming recent version of bash (4+) you could use associative arrays:
Code:
declare -A count
echo $((count[name]++))
This is assuming your variable called 'name'
Thanks, but where would I add this?
I don't see how this adds to "count" only when a test(ping) fails, or how it keeps a separate tally for each item in the list. I've tried googling around for the answer and have hit a brick wall.
I think you misunderstood my question: You need to insert that line exactly where you want to count something...
Here's how the script reads with that addition...
Code:
#!/bin/bash
# Declare 'count' array.
declare -A count
for i in {1..3600}
do
clear ; echo -e "Interval $i"
while IFS=, read name ip
do
ping -c 1 $ip >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo -e "\e[31;1mName: $name\t$ip \t- down.\e[0m\tCount: $((count[name]++))"
else
echo -e "\e[32;1mName: $name\t$ip \t- up!\e[0m\tCount: $((count[name]))"
fi
done < ~/monitor.txt
# 30 sec Countdown Timer
for i in {30..1};do echo -ne "\r$i" && sleep 1;echo -ne "\r "; done
done
Only the "down"(fail) line adds to the count. However this only has one(1) counter. There are multiple IP's being tested and ALL fails are being added together. I need them in increment separately.
Current output (assuming "nat" fails 3 times out of 10...and "google" never fails)
Name: google 8.8.8.8 - Up! Count: 3
Name: nat 10.1.1.1 - down. Count: 3
What I need is:
Name: google 8.8.8.8 - Up! Count: 0
Name: nat 10.1.1.1 - down. Count: 3
If you are not interested in the up count and wish this to always be zero, then do not include the counter in the up portion just us a static zero.
Of course if you are interested in both up and down, then pan64's suggestion is the way to go.
@michaelk - did you try it? I think you will find that like inside (()) when a variable is inside [] for an array it is actually evaluated.
oops ... apologies michaelk, I forgot this was an associative array and not a numeric one ... you are correct that it needs the $ to draw the string from it
Last edited by grail; 04-01-2015 at 09:53 AM.
Reason: I made a boo boo
I'm trying to make my question as simple as possible as I'm assuming people just aren't understanding the desired outcome.
1) The script reads a text(CSV) list of names and IP's.
2) The first IP on the list is pinged.
3)
---a--- IF down the script prints "Name <ip> - down Count: 1
---b--- IF up, the script prints "Name <ip> - up Count: 0
* 0 fails so far
4) The script now pings the next IP on the list.
---a--- IF down the script prints "Name <ip> - down Count: 1
---b--- IF up, the script prints "Name <ip> - up Count: 0
The screen now looks like this (assuming the 1st IP was up and the 2nd was down)
Name: google 8.8.8.8 - up! Count: 0
Name: nat 10.1.1.1 - down. Count: 1
5)A brief countdown occurs then the screen clears and the script starts the ping tests again.
* With the changes recommended above I now get...
Name: google 8.8.8.8 - up! Count: 1
Name: nat 10.1.1.1 - down. Count: 2
See the problem? It's combining ALL fails. I need them separate. The desired output would look like this (assuming the 1st item continues passing and the 2nd continues to fail)
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.