bash script for run another script after 5 unreachable ping request to specific ip or website - linux

I need script to run another script after 5 consistently 'unreachable' response from ping to specific ip. But if everything okay do nothing. For example for now I have script running ping command by taking ip addresses from text file which has list of ip or websites. And this script run another telegram message sending script if the ip or website from list is unreachable. But it is not good idea because often there can be just 1 unreacable response but overall the website is working or ip is reachable. Now I need the script which runs telegram message sending script after consistently 5 unreachable response. Not after 1 unreachable response. Here's my script:
date
cat /home/user/list.txt | while read output
do
ping -c 1 "$output" > /dev/null
if [ $? -eq 0 ]; then
echo "node $output is up"
else
message="$(echo "node $output is down")"
echo "node $output is down" > /home/user/siteDown.log
telegram-send "$message"
fi
done
Thank to all, have a nice days.

Try this:
#!/bin/sh
try_ping() {
i=0
while [ $((i+=1)) -le 5 ] ; do
ping -c 1 "${1}" > /dev/null \
&& return 0
sleep 0.5
done
return 1
}
date
while read -r output ; do
if try_ping "${output}" ; then
echo "node $output is up"
else
echo "node $output is down" >> /home/user/siteDown.log
telegram-send "node $output is down"
fi
done </home/user/list.txt
I added a 0.5 second sleep after every ping attempt, but you can adjust that.

Related

Linux shell (sh) CLI test if ping successful

How to wire linux shell (sh) script to test with ping if host is reachable?
I guess there could be solution that uses grep but maybe ping provides that option by itself?
I am more into getting a whitelisting a successful ping operation that reached the host then checking if there was any error. I don't care about the reason of ping not succeeding in reaching a host.
I would like to limit ping attempts count and maximum amount of time to reach the host so the script does not waits too long for ping trying to reach a host.
dt=$(date +%d)
cksize=50
echo "Start $(date)"
while IFS= read -r sn
do
echo "*************************************************"
echo "Begin checking NODES client: $sn"
if ping -c 1 "$sn" -i 5 > /dev/null
then
echo "$sn node up"
else
echo "$sn node down"
fi
done < server_list
parallel -j0 --timeout 15 'ping -c 5 -i 0.2 {} >/dev/null 2>&1 && echo {} up || echo {} down' ::: freenetproject.org debian.org no-such.domain {1..254}.2.3.4
You can do it like this. It will do it in parallel for all hosts.
#!/bin/bash
for server in 'google.com' 'github.com' 'fakeserver.com'
do
{ ping -o "$server" &>/dev/null && echo "$server is UP" || echo "$server is DOWN" ; } &
done
wait
Regards!

Linux script to monitor remote port and launch script if not successful

RHEL 7.1 is the OS this will be used on.
I have two servers which are identical (A and B). Server B needs to monitor a port on Server A and if it's down for 30 seconds, launch a script. I read netcat was replaced with ncat on RHEL 7 so this is what I have so far:
#!/bin/bash
Server=10.0.0.1
Port=123
ncat $Server $Port &> /dev/null; echo $?
If the port is up, the output is 0. If the port is down, the output is 1. I'm just not sure on how to do the next part which would be "if down for 30 seconds, then launch x script"
Any help would be appreciated. Thanks in advance.
If you really want to script this rather than using a dedicated tool like Pacemaker as #CharlesDuffy suggested, then you could do something like this:
Run an infinite loop
Check the port
If up, save the timestamp
Otherwise check the difference from the last saved timestamp
If more time passed then threshold, then run the script
Sleep a bit
For example:
#!/bin/bash
server=10.0.0.1
port=123
seconds=30
seen=$(date +%s)
while :; do
now=$(date +%s)
if ncat $server $port &> /dev/null; then
seen=$now
else
if ((now - seen > seconds)); then
run-script && exit
fi
fi
sleep 1
done
#!/bin/bash
Server=10.0.0.1
Port=123
port_was_down=0
while true; do
sleep 30
if ! ncat $Server $Port &> /dev/null; then
if [[ $port_was_down == "1" ]]; then
run-script
exit
else
port_was_down=1
fi
else
port_was_down=0
fi
done
what about using nmap?
something like:
TIMEOUT=30s;
HOST=10.0.0.1;
PORT=123;
if nmap --max-rtt-timeout $TIMEOUT --min-rtt-timeout $TIMEOUT -p $PORT $HOST | grep "^$PORT.*open"; then
echo 'OPEN';
else
echo 'CLOSED';
fi;

Bash exit status when using while loop [duplicate]

This question already has answers here:
How to get the exit status a loop in bash
(8 answers)
Closed 7 years ago.
I have a bash script that goes through a list of ip's and pings them one by one. If the exit status for each ping is 0, then echo that the node is up, else the node is down.I am able to get this to work perfectly, but when the bash script ends the exit status is always 0.
What I am trying to achieve is for example out of 5 ip's if the 3rd one fails, to continue through the list and check the rest but once the script ends throw an exit status other than 0 and output which ip has failed.
cat list.txt | while read -r output
do
ping -o -c 3 -t 3000 "$output" > /dev/null
if [ $? -eq 0 ]; then
echo "node $output is up"
else
echo "node $output is down"
fi
done
thanks in advance!
Your first problem is that by doing cat file | while read you've spawned the while in its own subshell. Any variables it sets will only exist during that loop, so persisting a value will be difficult. More info on that issue here.
If you use while read ... done < file it will work correctly. Make an exit status flag that defaults to zero, but set it to one if any errors occur. Use it as your script's exit value.
had_errors=0
while read -r output
do
ping -o -c 3 -t 3000 "$output" > /dev/null
if [ $? -eq 0 ]; then
echo "node $output is up"
else
echo "node $output is down"
had_errors=1
fi
done < list.txt
exit $had_errors

How to ping several hosts at the same time (bash) linux

ip="192.168.129."
function addToList(){
list="$list $1"
}
addToList $1
for i in $ip{$list}
do
ping -c 1 $ip$1 > /dev/null
echo "Ping Status of $ip$1 : Success" ||
echo "Ping Status of $ip$1 : Failed"
done
How can i ping more than one host at the same time and show it in a list which ip address is up or down?
One way is to use a more powerful ping tool like fping.
The other approach is to run the pings in the background:
for ip in $*; do
if [[ "$ip" =~ "^[0-9]+$" ]]; then
ip="192.168.129.$ip"
fi
(
ping -c 1 $ip > /dev/null
if [ $? -eq 0 ]; then
echo "node $ip is up"
else
echo "node $ip is down"
fi
)&
done
(...)& runs a script in the background.
Here is a script I wrote after reading a similar post.
https://bitbucket.org/kurtjensen/nettest/src/master/
It can use multiple text files as possible configs and the config files give you a chance to name the ip address more descriptively. The example config files are
home.txt - Which is the default
momdad.txt - This is for my parents network
etc.
So I can run the script at home and just hit enter at the prompt or enter something like "momdad" to switch to a different config fo a different network.

Continue to grep for traceroute result with bash

Every night I go through the same process of checking failover systems for our T1's. I essentially go through the following process:
Start the failover process.
traceroute $server;
Once I see it's failed over, I verify that connections work by SSHing into a server.
ssh $server;
Then once I see it works, I take it off of failover.
So what I want to do is to continually run a traceroute until I get a certain result, then run a SSH command.
Put your list of successful messages in a file (omit the variable lines and fractions of the line, and use a ^ to identify the start of the line, as such:)
patterns.list:
^ 7 4.68.63.165
^ 8 4.68.17.133
^ 9 4.79.168.210
^10 216.239.48.108
^11 66.249.94.46
^12 72.14.204.99
Then a simple while loop:
while ! traceroute -n ${TARGET} | grep -f patterns.list
do
sleep 5 # 5 second delay between traceroutes, for niceness.
done
ssh ${DESTINATION}
Use traceroute -n to generate the output so you don't get an IP address that resolves one time, but and a name the next, resulting in a false positive.
I think you could be better off using ping command to verify server's accessability than traceroute.
It is easy to check for return status of ping command without using any grep at all:
if [ ping -c 4 -n -q 10.10.10.10 >/dev/null 2>& ]; then
echo "Server is ok"
else
echo "Server is down"
fi
If you want to do it continually in a loop, try this:
function check_ssh {
# do your ssh stuff here
echo "performing ssh test"
}
while : ; do
if [ ping -c 4 -n -q 10.10.10.10 >/dev/null 2>& ]; then
echo "Server is ok"
check_ssh
else
echo "Server is down"
fi
sleep 60
done

Resources