DNS A record and PTR record delete - linux

I have a duplicate in DNS record when adding new instance. My goal is to use "nsupdate" to be able to delete A record by IP if new instance IP is found. This is what I did. However, it didn't delete any duplicate when ran this script. what will be the best walk around?
domain=${domainname}
nodename=(hostname | awk -F. '{print $1}')
local_ip=$(ifconfig eth0 | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
nslookup ${local_ip} | grep SERVFAIL
if [[ $? < 0 ]] ; then
echo "Record already exists"
echo -e "update ${local_ip} IN A"
else
echo "creating forward Record: ${codename}.${domain}"
echo -e "update add ${nodename}.${domain} 3600 A ${local_ip}\nsend" | nsupdate -g
fi

It looks like you have several problems
Grep will not return a value less than 0, so your code to do your update will never run. Even if it did run, you're not echoing that command to nsupdate, so your record still wouldn't be changed. Also, there are several typos in your code
domain=${domainname}
nodename=(hostname | awk -F. '{print $1}')
local_ip=$(ifconfig eth0 | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
if nslookup ${local_ip} | grep SERVFAIL; then
echo "creating forward Record: ${nodename}.${domain}"
echo -e "update add ${nodename}.${domain} 3600 A ${local_ip}\nsend" | nsupdate -g
else
echo "Record already exists"
echo -e "update ${local_ip} IN A" | nsupdate -g
fi
I've never used nsupdate personally, but i'm assuming that you meant to send your update command to it in the same fashion as your 'add'.

Related

Using ssh inside a script to run another script that itself calls ssh

I'm trying to write a script that builds a list of nodes then ssh into the first node of that list
and runs a checknodes.sh script which it's self is just a for i loop that calls checknode.sh
The first 2 lines seems to work ok, the list builds successfully, but then I get either get just the echo line of checknodes.sh to print out or an error saying cat: gpcnodes.txt: No such file or directory
MYSCRIPT.sh:
#gets the master node for the job
MASTERNODE=`qstat -t -u \* | grep $1 | awk '{print$8}' | cut -d'#' -f 2 | cut -d'.' -f 1 | sed -e 's/$/.com/' | head -n 1`
#builds list of nodes in job
ssh -qt $MASTERNODE "qstat -t -u \* | grep $1 | awk '{print$8}' | cut -d'#' -f 2 | cut -d'.' -f 1 | sed -e 's/$/.com/' > /users/issues/slow_job_starts/gpcnodes.txt"
ssh -qt $MASTERNODE cd /users/issues/slow_job_starts/
ssh -qt $MASTERNODE /users/issues/slow_job_starts/checknodes.sh
checknodes.sh
for i in `cat gpcnodes.txt `
do
echo "### $i ###"
ssh -qt $i /users/issues/slow_job_starts/checknode.sh
done
checknode.sh
str=`hostname`
cd /tmp
time perf record qhost >/dev/null 2>&1 | sed -e 's/^/${str}/'
perf report --pretty=raw | grep % | head -20 | grep -c kernel.kallsyms | sed -e "s/^/`hostname`:/"
When ssh -qt $MASTERNODE cd /users/issues/slow_job_starts/ is finished, the changed directory is lost.
With the backquotes replaced by $(..) (not an error here, but get used to it), the script would be something like
for i in $(cat /users/issues/slow_job_starts/gpcnodes.txt)
do
echo "### $i ###"
ssh -nqt $i /users/issues/slow_job_starts/checknode.sh
done
or better
while read -r i; do
echo "### $i ###"
ssh -nqt $i /users/issues/slow_job_starts/checknode.sh
done < /users/issues/slow_job_starts/gpcnodes.txt
Perhaps you would also like to change your last script (start with cd /users/issues/slow_job_starts)
You will find more problems, like sed -e 's/^/${str}/' (the ${str} inside single quotes won't be replaced by a host), but this should get you started.
EDIT:
I added option -n to the ssh call.
Redirects stdin from /dev/null (actually, prevents reading from stdin).
Without this option only one node is checked.

echo text to multiple files in bash script

I am working on a bash script that uses pssh to run external commands, then join the output of the commands with the IP of each server. pssh has an option -o that writes a file for each server into a specified directory, but if the commands do not run, you just have an empty file. What I am having issues with is updating these empty files with something like "Server Unreachable" so that I know there was a connection issue reaching the server and to not cause problems with the rest of the script.
Here is what I have so far:
#!/bin/bash
file="/home/user/tools/test-host"
now=$(date +"%F")
folder="./cnxhwinfo-$now/"
empty="$(find ./cnxhwinfo-$now/ -maxdepth 1 -type f -name '*' -size 0 -printf '%f%2d')"
command="echo \$(uptime | awk -F'( |,|:)+' '{d=h=m=0; if (\$7==\"min\") m=\$6; else {if (\$7~/^day/) {d=\$6;h=\$8;m=\$9} else {h=\$6;m=\$7}}} {print d+0,\"days\",h+0,\"hours\",m+0,\"minutes\"}'), \$(hostname | awk '{print \$1}'), \$(sudo awk -F '=' 'FNR == 2 {print \$2}' /etc/connex-release/version.txt), \$(lscpu | awk -F: 'BEGIN{ORS=\", \";} NR==4 || NR==6 || NR==15 {print \$2}' | sed 's/ *//g') \$(free -k | awk '/Mem:/{print \$2}'), \$(df -Ph | awk '/var_lib/||/root/ {print \$2,\",\"\$5,\",\"}')"
pssh -h $file -l user -t 10 -i -o /home/user/tools/cnxhwinfo-$now -x -tt $command
echo "Server Unreachable" | tee "./cnxhwinfo-$now/$empty"
ls ./cnxhwinfo-$now >> ./cnx-data-$now
cat ./cnxhwinfo-$now/* >> ./cnx-list-$now
paste -d, ./cnx-data-$now ./cnx-list-$now >>./cnx-data-"$(date +"%F").csv"
I was trying to use find to locate the empty files and write "Server" unavailable using tee with this:
echo "Server Unreachable" | tee "./cnxhwinfo-$now/$empty"
if the folder specified doesn't already exist i get this error:
tee: ./cnxhwinfo-2019-09-03/: Is a directory
And if it does exist (ie, i run the script again), it instead creates a file named after the IP addresses returned by the find command, like this:
192.168.1.2 192.168.1.3 192.168.1.4 1
I've also tried:
echo "Server Unreachable" | tee <(./cnxhwinfo-$now/$empty)
The find command outputs the IP addresses on a single line with a space in between each one, so I thought that would be fine for tee to use, but I feel like I am either running into syntax issues, or am going about this the wrong way. I have another version of this same script that uses regular ssh and works great, just much slower than using pssh.
empty should be an array, assuming none of the file names will contain any whitespace in their names.
readarray -t empty < <(find ...)
echo "Server unreachable" | (cd ./cnxhwinfo-$now/; tee "${empty[#]}" > /dev/null)
Otherwise, you are building a single file name by concatenating the empty file names.

One ping two results

I'm sure there is an easy answer to this but not being too fluent in BASH I'm just going round in circles.
I want to do this
ping -c1 8.8.8.8 1>/dev/null 2>/dev/null
SUCCESS=$?
if [ $SUCCESS -eq 0 ] etc....
But then also assign that ping result to a variable so that I can get the time delay
ping -c1 8.8.8.8 1>/dev/null 2>/dev/null | DELAY=awk '{print $11}'
SUCCESS=$?
if [ $SUCCESS -eq 0 ] etc....
echo $DELAY
Thanks
There are multple issues with your code. One is already addressed by tink. If you do
ping -c1 8.8.8.8 1>/dev/null 2>/dev/null | cat
you first put all the stdout of the ping in /dev/null and then hope t get some stdout in your pipe. That won't work.
Second, the syntax
ping -c1 8.8.8.8 1>/dev/null 2>/dev/null | DELAY=awk '{print $11}'
is not correct. You will probably get a message
-bash: {print $11}: command not found
That is: the DELAY=awk syntax is used to set the variable DELAY to 'awk' for the execution the '{print $1}' command. That is not what you want to do.
Note also, that $? is the exit-code of the last command. So, if the previous line would have worked, $? would be the result of the awk and no longer of the ping.
Finally, when I do a ping, awk '{print $11}' just gives me a bunch of empty lines.
So, what to do? Fro example:
tempfile=/tmp/tempfile.$$
host=8.8.8.8
ping -c1 $host > $tempfile
success=$?
if [ $success -eq 0 ] ; then
sed -n 's/.*time=//p' $tempfile
else
echo "AAaarrghh... My Ping FAILED"
fi
rm $tempfile
or something like that
Thanks everyone and yes I knew my code had errors but it was about trying to describe the problem. I ended up going with this:-
PING=$(ping -c1 8.8.8.8 2>&1);
SUCCESS=$?
DELAY=$(echo $PING | awk '{print $14}' | awk -F= '{print $2}')
if [ $SUCCESS -eq 0 ]
then
echo $DELAY
else
echo 0
fi

bash script while loop

hi i am new in bash scripting.
This is my script in this i use while loop this is working till giving input to ping the ips in serverfile but further i want to use those ips to make files of each ip as below i am doing but it has some issue i think there must be more while loops in it . but its not working it takes only one ip as input and make the only one file and further adding in the required file its not working on whole input lets say there are 5 ips in the file it only make the first ip file.
#!/bin/bash
l2=$(tail -1 /root/serverfile | grep hadoop | tr ' ' '\n' | grep hadoop)
awk '{print $1}' < serverFile.txt | while read ip; do
if ping -c1 $ip >/dev/null 2>&1; then
cd /usr/local/nagios/etc/objects/Hadoop
cp Hadoop-node.cfg $l2.cfg
sed -i 's/192.168.0.1/'$ip'/' $l2.cfg
sed -i 's/Hadoop-node/'$l2'/' $l2.cfg
echo "cfg_file=/usr/local/nagios/etc/objects/Hadoop/$l2.cfg" >> /usr/local/nagios/etc/nagios.cfg
service nagios restart
echo " Node is added successfull"
echo $ip IS UP
else
echo $ip IS DOWN NOT PINGING
fi
done

Bash script to sort input file before piping to while loop

I have this bash script:
while IFS='"' read -r a ip c
do
echo "ip: $ip"
whois "$ip" | grep netname
done < <(head -10 file.log)
How can I sort the file.log file (e.g. with sort -n -r) before the first ten lines are taken and handed over to the while-loop?
If you want to get the top 10 lines after sorting, just sort it before using head:
while IFS='"' read -r a ip c
do
echo "ip: $ip"
whois "$ip" | grep netname
done < <(sort file.log | head -10)
^^^^^^^^^^^^^^^
Apply the sort flags you require, of course.
Use this command,
sort -nr file.log | head -10

Resources