Creating a shell script to check network connectivity - bash

I'm making a simple shell script that runs an infinite loop, then if the output of the ping command contains "time" (indicating that it pinged successfully) it should echo "Connected!", sleep 1, and clear. However, I get no output from my script.
#!/bin/bash
while :
do
if [[ $(ping google.com) == *time* ]];
then
echo -en '\E[47;32m'"\033[1mS\033[0m"
echo "Connected!"
else
echo -en '\E[47;31m'"\033[1mZ\033[0m"
echo "Not Connected!"
fi
clear
sleep 1
done

Your script is not giving output because ping never terminates. To get ping to test your connectivity, you'll want to give it a run count (-c) and a response timeout (-W), and then check its return code:
#!/bin/bash
while true
do
if ping -c 1 -W 5 google.com 1>/dev/null 2>&1
then
echo "Connected!"
break
else
echo "Not Connected!"
sleep 1
fi
done
ping will return 0 if it is able to ping the given hostname successfully, and nonzero otherwise.
It's also worth noting that an iteration of this loop will run for a different period of time depending on whether ping succeeds quickly or fails, for example due to no network connection. You may want to keep the iterations to a constant length of time -- like 15 seconds -- using time and sleep.

Related

Wait until a condition becomes true in bash

When writing shell scripts, I repeatedly have the need to wait for a given condition to become true, e.g. a remote URL becoming available (checked with curl) or a file that should exist, etc.
Ideally, I'd like to have a function or script await such that I can write, e.g.,
await [[ some condition ]]
and it would check the condition every second until it becomes true or a timeout occurs. Ideally I can set the polling interval and the timeout.
Is there a tool for this out there?
You can use an until loop:
until some condition
do
sleep 5
done
e.g.
until nc -z localhost 22
do
echo "SSHd is not up yet. Waiting..."
sleep 5
done
If you want to add a timeout, you'll have to add that separately with a counter or using the internal SECONDS variable:
SECONDS=0
until nc -z localhost 22
do
if (( SECONDS > 60 ))
then
echo "Giving up..."
exit 1
fi
echo "SSHd is not up yet. Waiting..."
sleep 5
done
I'd use the timeout utility around a while loop that uses sleep.
E.g.:
timeout 1 bash -c 'while :; do echo check; sleep 0.1; done '

How to adjust this bash script to run telnet commands successfully while being in SSH?

I am attempting to write a bash script that will do the following work flow:
Telnet into networked device via IP address on port 9100 telnet x.x.x.x 9100
Run SGD command ! U1 getvar \"internal_wired.ip.timeout.value\".
Expect output value of "10".
Here is the bash script I've written so far:
#!/bin/bash
IP=(x.x.x.x)
for i in ${IP}
do
echo " "
echo "Welcome! This script will check the timeout value of this networked device."
echo "The expected output should be `"10`". Let's get started!!"
echo " "
sleep 4
echo "5....."
sleep 1
echo "4...."
sleep 1
echo "3..."
sleep 1
echo "2.."
sleep 1
echo "1."
sleep 1
echo " "
telnet ${i} 9100 << END_SSH
sleep 5
getvar \"internal_wired.ip.timeout.value\"
sleep 5
END_SSH
done
When I run this script via bash mycode.sh, I get the following output in Terminal.app:
$ bash mycode.sh
Welcome! This script will check the timeout value of this networked device.
The expected output should be "10". Let's get started!!
5.....
4....
3...
2..
1.
Trying x.x.x.x...
Connected to x.x.x.x.
Escape character is '^]'.
Connection closed by foreign host.
[user#server ~]$
x.x.x.x is an IP placeholder just to add.
In theory, after the Escape character is '^]'. line, the script should have ran the ! U1 getvar "internal_wired.ip.timeout.value\" command.
Also, we should have had an expected output of "10".
When I first wrote this script, I initially did not have the END_SSH command in it. A colleague introduced that to me and said to wrap the telnet commands in the END_SSH because of how Terminal technically jumps out of SSH when you are in telnet. I've tried utilizing END_SSH, but am not successful.
How do I get the telnet command to run successfully and get the expected output value?
You misunderstand what "END_SSH" is. It's not a "command" - it's what's called "Here-document" in bash.
Essentially the text between the <<END_SSH and the END_SSH is a "here-document" that is piped into stdin of telnet ${i} 9100. So, the sleep 5 commands are never actually executed and the input reaches EOF before the connection is even established.
I don't know what exactly you are trying to accomplish, but I would guess that the following will work better. Oh, and what's with that weird IP=(x.x.x.x) declaration? Is that supposed to be an array?
#!/bin/bash
declare -a IP=(1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4)
for i in "${IP[#]}"; do
echo " "
echo "Welcome! This script will check the timeout value of this networked device."
echo "The expected output should be \"10\". Let's get started!!"
sleep 4
for j in {5..1}; do
echo $j
sleep 1
done
{ sleep 5; echo -n $'! U1 getvar "internal_wired.ip_timeout.value"\n'; sleep 5; } | telnet ${i} 9100
done
so here is what I suggest to use for the telnet part. Connect is a function being called later in a while loop, which will run over IPs ready from a file.
Connect()
{
(
sleep 10 # depending upon your network and device response, better to keep this first sleep value a little high
echo "command 1"
sleep 2
echo "command 2"
sleep 2
) | telnet $1 9100 | tee -a ${1}.log
}
while read -r IP
do
Connect $IP
done < filewithIPs

I want to open a netcat connection and keep sending some text forever

echo " The NC send commands on port 2612"
while :
do
echo "hello " | nc -q -1 <some IP> 2612
done
I want open a netcat session forever, and that is been achived by -q -1.
How can I send "hello" on the same channed in every 20 second.
my earlier script was as following, but that opens nc connection every time.
What I really want is to open connection once and send "echo hello" evey 20 sec.
while :
do
echo "hello " | nc 192.168.100.161 2612
sleep 20
done
while echo "hello"; do
sleep 20
done | nc -q 192.168.100.161 2612
Note that we moved the echo into the condition of the loop, so that we stop trying to run it if nc exits (causing the echos to fail).
If you want to be able to retain state (for instance, a counter) from inside the loop and access it after the pipeline exited, then things need to change a bit further:
#!/bin/bash
# ^^^^- process substitutions aren't part of POSIX sh
count=0
while echo "hello"; do
(( ++count ))
sleep 20
done > >(nc -q 192.168.100.161 2612)
echo "Ran $count loops before exiting" >&2
There, the redirection is done as a process substitution, and the loop takes place inside the same shell instance that continues after it exits. See BashFAQ #24 for more details on this problem and solution.

sshpass exit in automation

I have total of 6 IP addresses and out of the 6 only 2 IP addresses are valid. I wrote a shell script to use sshpass to test each IP.
The issue is when script reaches IP that is working it log's in the system (Cisco switch) and stays there and not continuing with the loop to test the remaining IPs. If i type "exit" on the system than it continues with the loop.
After a successful login how can script automatically get out, from logged system, and continue with testing remaining IP?
/usr/bin/sshpass -p $ADMINPASS ssh -oStrictHostKeyChecking=no -oCheckHostIP=no -t $ADMINLOGIN#$IP exit
i can use the exit status to figure out which IP worked and which on didn't work.
Test first if IP is alive, and then 'ssh' on it, could help you.I don't know if you are using a loop or not, but loop can be a good choice.Should look like : for f in ip-1 ip-2 ip-3 ip-4 ip-5 ip-6; do ping -c 1 -w 3 $f; if [ $? -eq 0 ]; then echo OK; ssh_pass $f your_command; else echo " IP is NOK"; fi; done
You can then also add 'exit' command, depending on what you test : 'exit 0' if it is OK, after you 'ssh' command, 'exit 1' if NOK.

Making bash script to check connectivity and change connection if necessary. Help me improve it?

My connection is flaky, however I have a backup one. I made some bash script to check for connectivity and change connection if the present one is dead. Please help me improve them.
The scripts almost works, except for not waiting long enough to receive an IP (it cycles to next step in the until loop too quick). Here goes:
#!/bin/bash
# Invoke this script with paths to your connection specific scripts, for example
# ./gotnet.sh ./connection.sh ./connection2.sh
until [ -z "$1" ] # Try different connections until we are online...
do
if eval "ping -c 1 google.com"
then
echo "we are online!" && break
else
$1 # Runs (next) connection-script.
echo
fi
shift
done
echo # Extra line feed.
exit 0
And here is an example of the slave scripts:
#!/bin/bash
ifconfig wlan0 down
ifconfig wlan0 up
iwconfig wlan0 key 1234567890
iwconfig wlan0 essid example
sleep 1
dhclient -1 -nw wlan0
sleep 3
exit 0
Here's one way to do it:
#!/bin/bash
while true; do
if ! [ "`ping -c 1 google.com; echo $?`" ]; then #if ping exits nonzero...
./connection_script1.sh #run the first script
sleep 10 #give it a few seconds to complete
fi
if ! [ "`ping -c 1 google.com; echo $?`" ]; then #if ping *still* exits nonzero...
./connection_script2.sh #run the second script
sleep 10 #give it a few seconds to complete
fi
sleep 300 #check again in five minutes
done
Adjust the sleep times and ping count to your preference. This script never exits so you would most likely want to run it with the following command:
./connection_daemon.sh 2>&1 > /dev/null & disown
Have you tried omitting the -nw option from the dhclient command?
Also, remove the eval and quotes from your if they aren't necessary. Do it like this:
if ping -c 1 google.com > /dev/null 2>&1
Trying using ConnectTimeout ${timeout} somewhere.

Resources