HowtoForge Forums | HowtoForge - Linux Howtos and Tutorials

HowtoForge Forums | HowtoForge - Linux Howtos and Tutorials (http://www.howtoforge.com/forums/index.php)
-   Programming/Scripts (http://www.howtoforge.com/forums/forumdisplay.php?f=7)
-   -   bash script to change dns on ping fail (http://www.howtoforge.com/forums/showthread.php?t=61681)

K_meleonu 1st May 2013 18:22

bash script to change dns on ping fail
 
Hello to all,
It seems today i am a little or more stupid.
I am trying to write a bash script wich should change the actual dns servers with new ones if ping geths ping: unknown host domain.com or a loss ower 20% or ping fails.

If is someone here who wants to help me or knows a script to do what i nees please post it here.
Will be much apreciate.

Thank you all in advance.

P.S.
The script i wrote and does now work is:
Code:

#!/bin/bash
PING=`ping -c 5 yahoo.com | grep packets | awk '{print $1 $4 $6}' | cut -c 1-3`;
RASPUNS="550";
DNSACT=`tail -n 2 /etc/resolv.conf`;
DNS1=`cat dns1 > /etc/resolv.conf`;
DNS2=`cat dns2 > /etc/resolv.conf`;
DNNS1=`cat dns1`;
DNNS2=`cat dns2`;
if [ "$PING" -ne "$RASPUNS" ];
then
{
if ["$DNSACT" = "$DNS1"]
then {
echo $DNS2;
}
else {
echo $DNS1;
}
fi
}
else
{
echo "yahoo.com raspunde";
}
fi

in file dns1 i have nameserver x.x.x.x and nameserver x.x.x.y
in file dns2 i have nameserver w.w.w.w and nameserver w.w.w.q

This script should do the following:
ping 5 times yahoo.com. If the result is not equal with 550 (means 5 packets sent, 5 packets received and 0% loss) it check's if actual dns servers are the same with the dns servers from dns1 file.
If they are the same the script should put in /etc/resolv.conf the dns servers from file dns2. If they are not the same the script should put in /etc/resolv.conf the dns servers from dns1 file.

K_meleonu 1st May 2013 19:22

Hello again to all,
I have modifyed the script to this:
Code:

#!/bin/bash
PING=`ping -c 5 yahoo.com | grep packets | awk -F% '{print $1 $4 $6}' | cut -c 36-38`;
RASPUNS="20";
DNSACT=`tail -n 2 /etc/resolv.conf`;
DNNS1=`cat dns1`;
DNNS2=`cat dns2`;
if [[(" $PING" > "$RASPUNS") || ("$DNSACT" = "$DNS1")]];
then
{
cat dns2 > /etc/resolv.conf;
}
else
{
cat dns1 > /etc/resolv.conf;
}
fi

It works fine exceptin when the ping answer is ping: unknown host yahoo.com. If i receive this answer the script terminates and doen not change the dns servers.

Still waiting for some help.
Thank you all in advance

sjau 6th May 2013 14:55

here's a bit an improved version (bash-wise)

Code:

#!/bin/bash
# Don't use ALLCAPS for custom variables. By convention only Environmental vars are ALLCAPS
makeping=$(ping -c 5 "yahoo.com" | grep "packets" | awk -F% '{print $1 $4 $6}' | cut -c 36-38)
raspuns="20";

dnsact=$(tail -n 2 "/etc/resolv.conf")
dnns1=$(cat dns1)
dnns2=$(cat dns2)

if [[ "${makeping}" -gt "${raspuns}" || "${dnsact}" = "${dns1}" ]]
then
    cat "dns2" > "/etc/resolv.conf"
else
    cat "dns1" > "/etc/resolv.conf"
fi

As for the problem, I have no idea.

K_meleonu 7th May 2013 08:24

Thank you for your reply and improvement. For me, the script worked even witll all caps (tested on ubuntu 12.0.4 LTS, Mandriva 2010 / 2011, Fedora 16).
The problem for wich i didn't found a solution yet is the one stated in the post above. If the answer is unknown host the script stops.
The only solution i found is to modify the host (in this case yahoo.com) with an IP address. But if that IP of yahoo.com fails then i will get a false response.
If i use the host, even if the IP fails at first check, at the second check the IP will be another one.

Again thank you for the improvement.

Best regards

sjau 7th May 2013 08:25

as said, you shouldn't use ALLCAPS on vars. Also use $() to run commands instead of backticks.

K_meleonu 15th September 2013 11:39

Here is the solution
 
Code:

#!/bin/bash
PING=`ping -c 5 yahoo.com | grep packets | awk -F% '{print $1 $4 $6}' | cut -c 36-38`;
RASPUNS="20";
DNSACT=`tail -n 2 /etc/resolv.conf`;
DNNS1=`cat dns1`;
DNNS2=`cat dns2`;
if [[(" $PING" > "$RASPUNS") || ("$DNSACT" = "$DNS1")]];
then
{
cat dns2 > /etc/resolv.conf;
}
else
{
cat dns1 > /etc/resolv.conf;
}
fi

This script will ping yahoo.com 5 times. If the ping result shows a loos ower 20% it will change the DNS servers.
You will have to create 2 files named dns1 and dns2 in wich you have to write your nameserver x.x.x.x and nameserver y.y.y.y and nameserver x.x.x.x-alternative and nameserver y.y.y.y-alternative and run the script into a cron job.

Marios Zindilis 22nd September 2013 11:25

Here's a potential problem with the script: ping performs two DNS resolutions during its operation:
  1. resolves yahoo.com to an IP, then
  2. resolves that IP back to a fully qualified domain name.

For example:
Code:

marios@yovan ~ $ ping -c 1 yahoo.com
PING yahoo.com (206.190.36.45) 56(84) bytes of data.
64 bytes from ir1.fp.vip.gq1.yahoo.com (206.190.36.45): icmp_req=1 ttl=49 time=306 ms

--- yahoo.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 306.046/306.046/306.046/0.000 ms

You can see that ping resolved yahoo.com to 206.190.36.45 and then resolved again 206.190.36.45 to ir1.fp.vip.gq1.yahoo.com (the FQDN).

If by coinsidence, the FQDN contains the word "packets", this will throw off your grep. So a small improvement to your script would be to add the -q option to ping (stands for "quiet"), so that the output is only the summary lines:
Code:

marios@yovan ~ $ ping -q -c 5 yahoo.com
PING yahoo.com (98.139.183.24) 56(84) bytes of data.

--- yahoo.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4003ms
rtt min/avg/max/mdev = 180.680/221.430/286.038/42.478 ms


K_meleonu 22nd September 2013 15:44

Hello there,
You are right but you can also use ping 8.8.8.8 (google dns) or other yahoo.com or google.com IP address instead of domain name.


All times are GMT +2. The time now is 00:49.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.