How to ping several hosts at the same time (bash) linux - 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.

Related

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

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.

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!

SSH Remote command exit code

I know there are lots of discussions about it but i need you help with ssh remote command exit codes. I have that code:
(scan is a script which scans for viruses in the given file)
for i in $FILES
do
RET_CODE=$(ssh $SSH_OPT $HOST "scan $i; echo $?")
if [ $? -eq 0 ]; then
SOME_CODE
The scan works and it returns either 0 or (1 for errors) or 2 if a virus is found. But somehow my return code is always 0. Even, if i scan a virus.
Here is set -x output:
++ ssh -i /home/USER/.ssh/id host 'scan Downloads/eicar.com; echo 0'
+ RET_CODE='File Downloads/eicar.com: VIRUS: Virus found.
code of the Eicar-Test-Signature virus
0'
Here is the Output if i run those commands on the "remote" machine without ssh:
[user#ws ~]$ scan eicar.com; echo $?
File eicar.com: VIRUS: Virus found.
code of the Eicar-Test-Signature virus
2
I just want to have the return Code, i dont need all the other output of scan.
!UPDATE!
It seems like, echo is the problem.
The reason your ssh is always returning 0 is because the final echo command is always succeeding! If you want to get the return code from scan, either remove the echo or assign it to a variable and use exit. On my system:
$ ssh host 'false'
$ echo $?
1
$ ssh host 'false; echo $?'
1
$ echo $?
0
$ ssh host 'false; ret=$?; echo $ret; exit $ret'
1
$ echo $?
1
ssh returns the exit status of the entire pipeline that it runs - in this case, that's the exit status of echo $?.
What you want to do is simply use the ssh result directly (since you say that you don't want any of the output):
for i in $FILES
do
if ssh $SSH_OPT $HOST "scan $i >/dev/lull 2>&1"
then
SOME_CODE
If you really feel you must print the return code, that you can do that without affecting the overall result by using an EXIT trap:
for i in $FILES
do
if ssh $SSH_OPT $HOST "trap 'echo \$?' EXIT; scan $i >/dev/lull 2>&1"
then
SOME_CODE
Demo:
$ ssh $host "trap 'echo \$?' EXIT; true"; echo $?
0
0
$ ssh $host "trap 'echo \$?' EXIT; false"; echo $?
1
1
BTW, I recommend you avoid uppercase variable names in your scripts - those are normally used for environment variables that change the behaviour of programs.

grep statement in bash

I am using a for loop to connect to a list of servers and perform some simple commands. If the server is not accessible then stderr is written to a file. I then grep that file for the server name. It seems relatively simple and for some reason it isn't working. For troubleshooting purposes I have narrowed my server list to two servers and only run simple commands.
for i in $(cat serverlist)
do
nexec -i $i hostname 2>>errorlog.txt
if grep -q $i errorlog.txt; then echo "error accessing" $i
else echo "was able to connect to" $i
fi
done
So in the serverlist I have defined two incorrect hosts for troubleshooting purposes. Nexec tries to connect to each and perform the hostname command. If it is unable to connect an error message is printed to errorlog.txt
e.g.,
nexec: Error accessing host test1
Since both servers are incorrectly specified I am not able to connect to either. Again for troubleshooting purposes.
When grep runs the first time against $i which is the first server in the list it doen't find any matches in error.txt. However, it should. If I cat the results instead of grepping it is there.
I am actually doing this in bladelogic so the rules are a bit different. It should still work.
while read -r i <&3; do
nexec -i "$i" hostname 2>>"errorlog.$i.txt" || {
echo "nexec for $i exited with status $?" >&2
continue
}
# check for case where it claimed success but actually failed
# if nexec is written correctly, you don't need any of this logic
# ...and can completely remove the rest of the loop.
if grep -q -e "$i" "errorlog.$i.txt"; then
echo "error accessing $i" >&2
else
echo "was able to connect to $i" >&2
fi
done 3<serverlist
# and combine all the individual logs into one file:
cat errorlog.*.txt >errorlog.txt && rm -f -- errorlog.*.txt
Not familiar with nexec, but I imagine something like this is what you are looking for
for i in $(cat serverlist)
do
if [ ! "$(nexec -i $i hostname)" ]
then echo "error accessing" $i
else echo "was able to connect to" $i
fi
done

linux script to test connectivity IP

Any idea how to create a script in order to test connectivity with IP that represents a default gateway. And in case of connectivity, to print the message "Default gateway up" and if it's not connected to give a message "Default gateway down"
#!/bin/bash
ping -c 1 192.168.1.1 2>&1 > /dev/null
if [ $? -ne 0 ]
then
echo -e "host does not respond to ping"
fi
Put this script in crontab and let it run every min or whatever frequency you want.

Resources