At first I thought it was a bit strange to let my code get examined in this way, but I'm glad I did as it was quite educational. I can only hope there was something in it for you as well.
Quote:
"tail -n+5" should give everything from line 5 and onward.
|
As I wrote, I tested this, but.....
I'm a believer so I tested it again. It DOES work.
I don't really understand what happened when I tried it before...
Must have been too tired..
changed....
Code:
host -t ${TYPE} ${NAME} ${NAMESERVER} | tail -n+6 | sort -dbo "${REF}"
PS I think I know why I thought it didn't work. I probably tried "tail -n+1" and expected it to skip the first line, which it didn't.
Quote:
However, I would suggest controlling debug level with an option:
|
Code:
DEBUG=0
while getopts rvt: name
do
case $name in
r) WRITE_REF=1;;
t) TYPE="$OPTARG";;
v) let DEBUG+=1;;
?) printf "Usage: %s: [-r] [-t TYPE] [-v] domain\n" $0
exit 2;;
esac
done
shift $(($OPTIND - 1))
Quote:
you've seen that it's annoying when commands act differently depending on context, so you should avoid doing this when writing your own commands.
|
I'm gonna pass on this advice for this script, although I think you're right. In this script I'm combining "verbosity" with "debuginfo" which is not good a thing. I Will think of a better structure in my next script.
Quote:
Also you should probably echo debug output to standard error.
|
Code:
verbose ()
{
if [ ! $VERBOSE = 0 ]; then
echo "$*"
fi
}
debug ()
{
if [ ! $DEBUG = 0 ]; then
echo "$*" >&2
fi
}
Quote:
Or you could use tty which tells you if standard in is connected to a terminal.
|
Code:
HEADLESS=0
! tty | grep -q pts && HEADLESS=1
# Raise debuglevel by 1 if the script is invoked from the console
[ ${HEADLESS} == 0 ] && let DEBUG+=1
Quote:
Because you used "|" this command actually runs in a new subshell, so the try variable in the main script doesn't get incremented. You can use redirection instead:
|
I already noticed that behaviour, but didn't know the exact reason. I thought it had to do with the while loop. Because of that I already saved $NAMESERVER to a file... I casually added $try later on (forgot this behaviour) and never noticed it wasn't working because it's quite exceptional the loop runs more than 1 time.
big THANKS!
Changed
Code:
try=1
cat $FTMP1 | while read NAMESERVER
do
[ $DEBUG -gt 1 ] && echo "Probing $NAMESERVER"
echo -e "$NAMESERVER" > $FTMP3
host -t soa ${TOPLEVEL} ${NAMESERVER} > $FTMP2
grep -q "has SOA record" $FTMP2 && break
let try+=1
done
NAMESERVER=`cat "$FTMP3"`
into
Code:
try=1
while read NAMESERVER
do
[ $DEBUG -gt 1 ] && echo "Probing $NAMESERVER" >&2
host -t soa ${TOPLEVEL} ${NAMESERVER} > $FTMP2
grep -q "has SOA record" $FTMP2 && break
let try+=1
done <$FTMP1
Quote:
I'd prefer mktemp instead of using the process id to avoid race conditions.
|
Looks better, yes...
Code:
FTMP1=`mktemp`
FTMP2=`mktemp`
FTMP3=`mktemp`
Current code:
Code:
#!/bin/sh
# Author: JP van Melis
#
# Check a domain and report if the record has changed since you last generated a checkpoint (-r)
# It will check the SOA-record if the domain is a toplevel-domain.
# If not it will check the A-record unless it starts with an underscore (SRV) or you defined a type with -t
#
# Examples:
# chkdns domain.com check soa-record
# chkdns www.domain.com check A-record
# chkdns _sip._udp.domain.com check SRV-record
# chkdns -t mx domain.com check MX-record
# chkdns -r -t mx domain.com check MX-record and make a checkpoint
#
# It needs sendEmail (perl-script) to write you an eMail
# You can run it as a cronjob and it is intended as such.
# Then it will only send output if the records have changed so you can safely use procmail.
#
# I wrote it to check if my provider's SRV-records have changed.
#
# In /etc/cron.hourly you can put a script with this content:
#
# #!/bin/sh
# chkdns $* domain.com
# chkdns $* -t mx domain.com
# chkdns $* _sip._udp.domain.com
#
# If you run that script with the -r parameter it will write all the referenc-files
#
#
DEBUG=0
VERBOSE=0
WRITE_REF=0
while getopts rvt: name
do
case $name in
r) WRITE_REF=1;;
t) TYPE="$OPTARG";;
v) let DEBUG+=1
VERBOSE=1
;;
?) printf "Usage: %s: [-r] [-t TYPE] [-v] domain\n" $0
exit 2
;;
esac
done
shift $(($OPTIND - 1))
if [ -z "$1" ] ; then
NAME=`basename $0`
else
NAME="$1"
fi
verbose ()
{
if [ ! $VERBOSE = 0 ]; then
echo "$*"
fi
}
debug ()
{
if [ ! $DEBUG = 0 ]; then
echo "$*" >&2
fi
}
# I noticed that HISTSIZE is almost always set when you are running it from console
# Some small busybox systems don't have a history so I let it be triggered by the $TERM variable
# If someone knows a better way to determine if it's run from console, please let me know.
HEADLESS=0
! tty | grep -q pts && HEADLESS=1
# Raise debuglevel by 1 if the script is invoked from the console
[ ${HEADLESS} == 0 ] && let DEBUG+=1
NAME=`echo "${NAME}" | tr '[A-Z]' '[a-z]'`
DOTS=`echo "${NAME}" | grep -o "\." | wc -l`
TOPLEVEL=`echo "$NAME" | egrep -o "[a-z0-9-]*\.[a-z][a-z]*$"`
debug "Domain: ${NAME}"
debug "Toplevel: ${TOPLEVEL}"
if [ -z $TOPLEVEL ]; then
echo "Not a valid domain name given"
exit 1
fi
_sendmessage ()
{
if [ ${DEBUG} -ne 0 ] ; then
echo -e "\n${MESSAGE}\n"
cat "${MESSAGE_FILE}"
echo -en "\n"
fi
if [ ${HAS_MAILER} -ne 0 ] ; then
[ ${DEBUG} -gt 1 ] && echo -e "Mailing this change to ${MAILTO}"
sendEmail -f $MAILFROM -s $SMTPS -t $MAILTO -o tls=no -o message-file="${MESSAGE_FILE}" -u "${MESSAGE}" -q
fi
}
if [ -z "${TYPE}" ]; then
TYPE=A
[ "`echo ${NAME} | cut -b1`" = "_" ] && TYPE=SRV
[ ${DOTS} = 1 ] && TYPE=SOA
else
TYPE=`echo "${TYPE}" | tr '[a-z]' '[A-Z]' | egrep -o "^[A-Z]*$"`
if [ -z "${TYPE}" ]; then
echo "This is not a valid record-type"
exit 1
else
if [ -z "`echo ".A.AAAA.CERT.CNAME.DNAME.DNSKEY.IPSECKEY.LOC.MX.NAPTR.NS.PTR.SOA.SPF.SRV.SSHFP.TXT." | egrep -o "\.${TYPE}\."`" ]; then
echo "${TYPE} is not a known record-type"
exit 1
fi
fi
fi
debug "Type: $TYPE"
if [ "$TYPE" = "SRV" ]; then
if [ ! "`echo ${NAME} | egrep -o "_[a-z]*\._[tu][cd]p\." | wc -l`" = 1 ] || [ ! "`echo ${NAME} | egrep -o "_" | wc -l`" = 2 ]; then
echo "This is not a valid SRV-record, try this: $0 -t srv _sip._udp.$TOPLEVEL"
exit 1
fi
fi
DAILY_WARNING=1
SMTPS="192.168.10.25"
MAILFROM="${USER}@${HOSTNAME}"
MAILTO="yourmail@yourdomain.com"
MESSAGE_FILE="/tmp/${NAME}.${TYPE}.msg"
HAS_MAILER=0
[ ! -z "`which sendEmail 2>/dev/null`" ] && HAS_MAILER=1
REF="/var/run/${NAME}.${TYPE}.ref"
CUR="/var/run/${NAME}.${TYPE}.cur"
FTMP1=`mktemp`
FTMP2=`mktemp`
FTMP3=`mktemp`
#
# Determine which DNS-server to use
# It will try nameservers until it gets a valid reply.
# It will start with the Authorative NS, to get the most reliable answer.
#
host -t soa ${TOPLEVEL} | grep "has SOA record" | awk '{print $5}' >$FTMP1
host -t ns ${TOPLEVEL} | grep "name server" | awk '{print $4}' | sort -dbu >>$FTMP1
nNS=`cat ${FTMP1} | wc -l`
echo -e "208\.67\.220\.220\n" >>$FTMP1
try=1
while read NAMESERVER
do
[ $DEBUG -gt 1 ] && echo "Probing $NAMESERVER"
host -t soa ${TOPLEVEL} ${NAMESERVER} > $FTMP2
grep -q "has SOA record" $FTMP2 && break
let try+=1
done <$FTMP1
rm -rf "$FTMP1"
rm -rf "$FTMP2"
rm -rf "$FTMP3"
if [ ${try} == 1 ]; then
NSTYPE=" (primary Authorative)"
elif [ ${try} -le ${nNS} ]; then
NSTYPE=" (Authorative)"
elif [ ${try} -eq $((${nNS} + 1 )) ]; then
NSTYPE=" (OpenDNS)"
else
NSTYPE="(system)"
fi
verbose "Lookup ${TYPE}-record of ${NAME} using nameserver: ${NAMESERVER}${NSTYPE}"
if [ $WRITE_REF = 1 ]; then
if [ -z "${NAMESERVER}" ]; then
host -t ${TYPE} ${NAME} | sort -dbo "${REF}"
else
host -t ${TYPE} ${NAME} ${NAMESERVER} | tail -n+6 | sort -dbo "${REF}" fi
exit 0
fi
if [ -z "${NAMESERVER}" ]; then
host -t ${TYPE} ${NAME} | sort -dbo "${CUR}"
else
host -t ${TYPE} ${NAME} ${NAMESERVER} | tail -n+6 | sort -dbo "${CUR}"
fi
[ ${DEBUG} -ne 0 ] && cat "${CUR}"
if [ ! -f "${REF}" ]; then
echo -e "\nReference file does NOT exist.. Execute \"${0} -r ${NAME}\""
exit 1
else
DIFF="`diff "${REF}" "${CUR}"`"
REFDATE=`date +"%d-%m %H:%M" -r "${REF}"`
if [ -n "${DIFF}" ]; then
echo -e "Currently (`date +"%d-%m %H:%M"`) the answer from ${NAMESERVER}${NSTYPE} is:" >"${MESSAGE_FILE}"
cat "${CUR}" >>"${MESSAGE_FILE}"
echo -e "\r\nThe reference file (${REFDATE}) has this:" >> "${MESSAGE_FILE}"
cat "${REF}" >> "${MESSAGE_FILE}"
echo -e "\r\nIf you run \"${0} -r\", you can rewrite a reference file to stop these messages" >> "${MESSAGE_FILE}"
MESSAGE="${TYPE}-record of $NAME has changed!!!"
_sendmessage
elif [ "`date +%H`" == "00" ] && [ "`date +%M | cut -b1`" == "0" ] ; then
if [ ${DAILY_WARNING} -ne 0 ] ; then
MESSAGE="${TYPE}-record of $NAME is still the same as on ${REFDATE}"
cat "${CUR}" >"${MESSAGE_FILE}"
_sendmessage
fi
fi
rm -f "${MESSAGE_FILE}"
rm -f "${CUR}"
fi
rm -rf "$FTMP1"
rm -rf "$FTMP2"
rm -rf "$FTMP3"
exit 0