(2012-08-02) Some Bash Scripts

So I'm really no expert in bash scripting, but I figured that it would be good to get a collection of all my useful code in one place. And the first round of scripts is my first set of actually usable ones that I ever wrote.

You should probably be aware that I wont be taking any responsibility for the lack of optimisation or for any damage that you somehow incur using these...

All these scripts are provided as is under the Creative Commons BY-SA-NC licence

First up is a potentially useful tool for sending an email report (can set it up with a cron job) on whether a user account(s) is reaching it's hourly limit as set up in the exim config.

This only works with exim as that's what all our work servers run. The comments should explain pretty much everything it does.
#!/bin/bash #Original code by edgley #Email recipients, seperated with a comma sendTo="EMAIL@ADDRESS.HERE"; reportType=${1,,}; #Give a nicer name to the only input value (either `mail` or ``), case insensitive for compatibility getHostname=$(hostname); #Resolve the current server hostname theDate=$(eval date +%Y-%m-%d); #Get the current date and format it to match exim_mainlog exceededSearch="exceeded"; #Define what terms to search the exim log for if [[ $UID != 0 ]]; then #Check the script is running as root, if not thrown an error echo "You need to be root to run this script!"; exit 1; fi #Run the report, checking that the entries are only for today and it matches our search. We also then want to crop the results down as much as possible using awk exceededReport=$(cat /var/log/exim_mainlog | grep -i "$theDate" | grep -iF "$exceededSearch" | awk -F'[:]' '{ print $1, $3, $6 }' | awk -F'[,]' '{ print $1 }'); if [[ $exceededReport > 0 ]]; then #Check if the report returned anything if [[ $reportType == "mail" ]]; then #Check if we are emailing the report or not echo "START OF REPORT FOR $theDate"; echo "$exceededReport"; echo "END OF REPORT"; else #Email the report to sender list and format the email echo -e "START OF REPORT FOR $theDate\n$exceededReport\nEND OF REPORT" | /bin/mail -s "Potential Spammer Detected on $getHostname" "$sendTo"; fi else #If no errors came up, we are done; no need to send an email echo "No accounts have exceeded their hourly limits. This does not mean there isn't a spammer, only that there isn't any exim errors!"; fi exit 0; #Exit the script
Next up is my first attempt at some kind of formatting function, it simply allows for a more legible version of echo.
#! /bin/bash #Original code by edgley writer () { ## Start writer function intVar="${1,,}"; ## Define the first input case "$intVar" in ## Define avaliable modes for the writer function t|tab) ## Add tabs intCount="${2,,}"; ## Define the second input if [[ "$intCount" == "" ]]; then echo -ne "\t"; else escapeCount="0"; while [[ "$escapeCount" != "$intCount" ]]; do ## Repeat the escape code by the amount specified echo -ne "\t"; let escapeCount=escapeCount+1; done; fi; ;; b|break) ## Add line breaks intCount="${2,,}"; ## Define the second input if [[ "$intCount" == "" ]]; then echo -ne "\n"; else escapeCount=0; while [[ "$escapeCount" != "$intCount" ]]; do ## Repeat the escape code by the amount specified echo -ne "\n"; let escapeCount=escapeCount+1; done; fi; ;; *) ## As tabs and breaks can't be used in conjunction with text, we define everything else in the catch-all textType="${1,,}"; case "$textType" in ## Define avaliable text styles s|strong) ## Bold text textStyle="1"; textColour="${2,,}"; userText="$3"; ;; u|underline) ## Underline text textStyle="4"; textColour="${2,,}"; userText="$3"; ;; i|italic) ## Italic text, doesn't work in all terminals! textStyle="3"; textColour="${2,,}"; userText="$3"; ;; f|faint) ## Faint text, doesn't work in all terminals! textStyle="2"; textColour="${2,,}"; userText="$3"; ;; h|hidden) ## Invisible text (will create a space) textStyle="8"; textColour="${2,,}"; userText="$3"; ;; d|default) ## Normal text, not required, but used for consistency with lots of lines textStyle="0"; textColour="${2,,}"; userText="$3"; ;; *) ## We'll assume that anything else is expected to be printed textStyle="0"; textColour="${1,,}"; userText="$2"; ;; esac; case "$textColour" in ## Define avaliable colours r|red) colorText="\e[$textStyle;31m";; g|green) colorText="\e[$textStyle;32m";; y|yellow) colorText="\e[$textStyle;33m";; b|blue) colorText="\e[$textStyle;34m";; p|purple) colorText="\e[$textStyle;35m";; c|cyan) colorText="\e[$textStyle;36m";; w|white) colorText="\e[$textStyle;37m";; 0|black) colorText="\e[$textStyle;30m";; *) ## If no colour is defined case "$textType" in s|strong|u|underline|d|default|fb) ## Check if styling is applied userText="$2"; ## Define the second input as text colorText="\033[$textStyle""m"; ## Define the text styling without the colour ;; lc|linecont) ## Experimental multi line styling userText="$2"; ;; *) ## If no styling was applied userText="$1"; ## Define first input as text colorText="\033[0m"; ## We'll use the default style ;; esac; ;; esac; echo -ne "$colorText$userText\e[0m"; ## Output the final results to screen ;; esac; }; ## Usage: ## writer break|b INT -- Adds Line break(s), INT is number of breaks, blank is 1. ## writer tab|t INT -- Adds tab(s), INT is number of tabs, blank is 1. ## writer STYLE COLOR TEXT -- Prints text (with no breaks or tabs added) in style and color (both optional). ## Avaliable styles b|bold, u|underline, i|italic, f|faint, h|hidden, d|default. ## Avaliable colours r|red, g|green, y|yellow, b|blue, p|purple, c|cyan, w|white, 0|black. ## If you want multiple lines in the same style, use writer lc|linecont TEXT in all subsiquent lines. ## No style or colour defined will act exactly like echo -ne. You can still add escape codes inside.
The last script for now was my first "real" script, which is more of a wrapper for host, dig, ping and other DNS utilities. It requires the packages "dnsutils" and "whois". I went a bit mad with the commenting... But here it is in all its unrefined glory (it's a big'un).  
#!/bin/bash #Orginal code by edgley logEnabled='false'; # Enable the command logger logFile='.domaintools.log'; # Define file to log to debugEnabled='false'; # Enable the command debugger ( allows for you to run a command blind and see the last result) debugFile='.domaintools.debug.log'; # Define file to debug log to countryList=('au:202.83.95.227' 'de:178.63.26.173' 'ca:67.212.90.199' 'nz:27.110.120.30' 'uk:89.16.173.11' 'us:216.87.84.211' 'cz:31.31.78.164' 'fr:92.243.8.139' 'lu:195.46.245.59' 'nl:109.235.51.12' 'se:192.121.86.100'); # Define valid countries and their IP's pingData=('24' '54' '120' '248' '504' '1016' '2040' '4088'); # Define ping test loops showMenu () { # Menu function if [[ "$1" == '' ]]; then # If no menu item has been given, display the main menu echo -ne "\n\t\e[1;33mdomaintools Main Menu\033[0m\n"; # Display the header echo -ne "\e[1;36m\n\t[2|s] Set Domain name\n\t[3|l] Logging Options\n\t[4|b] Debug Options\n\t[5|H] Host Lookup\n\t[6|P] Ping Test\n\t[7|D] DNS Records\n\t[8|T] Trace Route\n\t[9|W] WHOIS Lookup\n\t[0|x] Exit script\033[0m\n"; # Display menu if [[ "$domainSet" == '' ]]; then # Check if a domain has been set echo -ne "\n\t\e[1;31mCurrently set domain:\033[0m None\n"; # Show that no domain has been set else # If a domain has been set echo -ne "\n\t\e[1;31mCurrently set domain:\033[0m $domainSet\n"; # Show the domain that has been set fi; # No need to check further echo -ne "\t\e[1;31mLogging Enabled:\033[0m $logEnabled\n"; # Show the logging status echo -ne "\t\e[1;31mDebugging Enabled:\033[0m $debugEnabled\n"; # Show the debug status read -n 1 -s menuOption; # Get the users input on what menu item they want case $menuOption in # Define the menu 2|s) showMenu setDomain;; # Check for set domain option 3|l) showMenu logOption;; # Check for logging option 4|b) showMenu bugOption;; # Check for debugging option 5|H) showMenu hostLookup;; # Check for host option 6|P) showMenu pingTest;; # Check for ping option 7|D) showMenu digLookup;; # Check for dig option 8|T) showMenu traceRoute;; # Check for trace option 9|W) showMenu whoisLookup;; # Check for whois option 0|x) showMenu quitMenu;; # Check for quit option esac; # End menu echo -ne "\n\n"; # Add spacing between the menu and the next command elif [[ "$1" == 'setDomain' ]]; then # If the user wants to set the domain echo -ne "\n\t\e[1;31mSet new domain or IP\033[0m"; # Help message echo -ne "\n\t\e[1;32mDomain:\033[0m "; # Ask the user what domain or IP they want to run queries on read userDomain; # Get the users input on what domain should be set if [[ "$userDomain" != '' ]]; then # Check if the suer actually entered something domainSet=${userDomain,,}; # Set the domain echo -ne "\t\e[1;31mNew Domain set to $domainSet!\033[0m\n\tPress any key to return to the menu.\n"; # Show the user the domain that has been set read -n 1 -s; # Wait for any key before continuing showMenu; # Go back to the main menu else # If the user didn't enter a domain name echo -ne "\t\e[1;31mDomain not set. You wont be able to run any commands.\033[0m\n\tPress any key to return to the menu.\n"; # Warn the user that nothing will work without a domain name read -n 1 -s; # Wait for any key before continuing showMenu; # Go back to the main menu fi; # No need to check further elif [[ "$1" == 'logOption' ]]; then # If the user wants to change the logging settings echo -ne "\n\t\e[1;31mEnable logging? (true or false)\033[0m"; # Help message echo -ne "\n\t\e[1;32mLogging:\033[0m "; # Ask if the user wants to enable or disable logging read userLog; # Get users input logEnabled=${userLog,,}; # make sure whatever the user inputs is in lowercase if [[ "$logEnabled" == 'true' ]]; then # If logging is set to true echo -ne "\n\t\e[1;31mSet log file (leave blank for default)\033[0m"; # Help message echo -ne "\n\t\e[1;32mLog file:\033[0m "; # Ask where the user wants to save the log read userLogFile; # Get users input if [[ "$userLogFile" == '' ]]; then # If no user log file is entered logFile='.domaintools.log'; # Use the default log file echo -ne "\t\e[1;31mLogging set to $logFile file!\033[0m\n"; # Show the user the file they are logging to else # If the user entered a filename logFile=$userLogFile; # Set the log file to the user entered file echo -ne "\t\e[1;31mLogging set to $logFile!\033[0m\n"; # Show the user the file they are logging to fi; # No need to check further else # If the user entered anything but true echo -ne "\t\e[1;31mLogging disabled!\033[0m\n"; # Warn the user fi; # No need to check further echo -ne "\tPress any key to return to the menu.\n"; # Tell the user to press any key read -n 1 -s; # Wait for any key to be pressed showMenu; # Show the main menu elif [[ "$1" == 'bugOption' ]]; then # Check if the debug option was selected echo -ne "\n\t\e[1;31mEnable debugging? (true or false)\033[0m"; # Help line echo -ne "\n\t\e[1;32mDebugging:\033[0m "; # Prompt the user for input read userBug; # Get the users input debugEnabled=${userBug,,}; # Set the debugging state if [[ "$debugEnabled" == 'true' ]]; then # If the use enabled debugging echo -ne "\n\t\e[1;31mSet debug log file (leave blank for default)\033[0m"; # Help line echo -ne "\n\t\e[1;32mLog file:\033[0m "; # Prompt the user for input read userBugFile; # Get the users input if [[ "$userBugFile" == '' ]]; then # If the user hasn't entered a debug file debugFile='.domaintools.debug.log'; # Define the default debug file echo -ne "\t\e[1;31mDebugging set to $debugFile file!\033[0m\n"; # Show the user the debug file is set to the default else # If the user specified a bug file debugFile=$userBugFile; # Set the debug file to the user specified file echo -ne "\t\e[1;31mDebugging set to $debugFile!\033[0m\n"; # Show the user what the debug file is now set as fi; # No need to check further else # If the user entered anything other than true echo -ne "\t\e[1;31mDebugging disabled!\033[0m\n"; # Debugging disabled fi; # No need to check further echo -ne "\n\tPress any key to return to the menu.\n"; # Tell the user to press any key read -n 1 -s; # Wait for any key to be pressed showMenu; # Show the main menu elif [[ "$1" == 'hostLookup' ]]; then if [[ "$domainSet" == '' ]]; then # If the user has not set a domain echo -ne "\n\tYou need to set a domain from the main menu first!"; # Tell the user to set a domain else # If the user has set the domain hostLookup $domainSet; # Run the host lookup function fi; # No need to check further echo -ne "\n\tPress any key to return to the menu.\n"; # Tell the user to press any key read -n 1 -s; # Wait for any key to be pressed showMenu; # Show the main menu elif [[ "$1" == 'pingTest' ]]; then if [[ "$domainSet" == '' ]]; then # If the user has not set a domain echo -ne "\n\tYou need to set a domain from the main menu first!"; # Tell the user to set a domain else # If the user has set the domain pingTest $domainSet; # Run the ping test function fi; # No need to check further echo -ne "\n\tPress any key to return to the menu.\n"; # Tell the user to press any key read -n 1 -s; # Wait for any key to be pressed showMenu; # Show the main menu elif [[ "$1" == 'digLookup' ]]; then if [[ "$domainSet" == '' ]]; then # If the user has not set a domain echo -ne "\n\tYou need to set a domain from the main menu first!"; # Tell the user to set a domain else # If the user has set the domain echo -ne "\n\t\e[1;31mEnter country code of DNS to use (leave blank for default)\033[0m"; # Help line echo -ne "\n\t\e[1;32mServer:\033[0m "; # Prompt the user for input read userCountry; # Get the users input if [ "$userCountry" != '' ]; then # If a country code is given for i in "${countryList[@]}"; do # Look through the array of avaliable name servers (configured above) countryCode=$(echo ${i:0:2}); # Strip the IP's from the array and give it a new name if [[ "$userCountry" == "$countryCode" ]]; then # If the user entered country code matches that of one of the array items oDns=$(echo ${i:3}); # Define the name server to use as the IP address listed with that country code break; # Leave the loop (No need to check further) else # If the user didn't enter a valid country code, keep checking until the array is exahusted oDns="89.16.173.11"; # Define the name server as that of the UK OpenNIC name server fi; # No need to check further done # Stop looking in the array once it's reached the end else # If no country code was given oDns="89.16.173.11"; fi; # No need to check further echo -ne "\n\t\e[1;31mEnter record type to lookup (leave blank for ANY)\033[0m"; # Help line echo -ne "\n\t\e[1;32mRecord:\033[0m "; # Prompt the user for input read userRecord; # Get the users input if [[ "$userRecord" == '' ]]; then # Check if a DNS record type to lookup was left blank usedRecord="ANY"; # Set the default record type else usedRecord="$userRecord"; fi; digLookup $domainSet $usedRecord $oDns; # Run the dig command with the final inputs fi; # No need to check further echo -ne "\n\tPress any key to return to the menu.\n"; # Tell the user to press any key read -n 1 -s; # Wait for any key to be pressed showMenu; # Show the main menu elif [[ "$1" == 'traceRoute' ]]; then # If the whois option was selected if [[ "$domainSet" == '' ]]; then # If the user has not set a domain echo -ne "\n\tYou need to set a domain from the main menu first!"; # Tell the user to set a domain else # If the user has set the domain traceRoute $domainSet; # Run the trace route function fi; # No need to check further echo -ne "\n\tPress any key to return to the menu.\n"; # Tell the user to press any key read -n 1 -s; # Wait for any key to be pressed showMenu; # Show the main menu elif [[ "$1" == 'whoisLookup' ]]; then # If the whois option was selected if [[ "$domainSet" == '' ]]; then # If the user has not set a domain echo -ne "\n\tYou need to set a domain from the main menu first!"; # Tell the user to set a domain else # If the user has set the domain whoisLookup $domainSet; # Run the whois function on the set domain fi; # No need to check further echo -ne "\n\tPress any key to return to the menu.\n"; # Tell the user to press any key read -n 1 -s; # Wait for any key to be pressed showMenu; # Show the main menu elif [[ "$1" == 'quitMenu' ]]; then # Check if the user opted to quit echo -ne "\n"; # Add a space after the menu (easier on the eye0 exit; # Leave the script else # If something went terribly wrong showMenu; # Show the main menu fi; # No need to check further } # End of menu function showHelp () { # All encompassing help function if [[ "$1" == 'full' ]]; then # Check if the full help output is called for helpTopic=${2,,}; # Check to see what help topic is being called for (internally) echo -ne "\nUsage: domaintools [COMMAND]... [DOMAIN]...\nOutputs results of multiple queries on a given domain or IP.\nRun domaintools for interactive mode.\n"; # Display the first block of fixed text if [[ "$helpTopic" == 'host' ]]; then # If the host topic is called, highlight the host line in red echo -ne "\n\t\e[1;31m\033[1m -H, --host DOMAIN\tRuns a query against OpenNIC nameservers around the world and outputs the first A record listed.\033[0m"; else # Otherwise just display it normally echo -ne "\n\t-H, --host DOMAIN\tRuns a query against OpenNIC nameservers around the world and outputs the first A record listed."; fi; # No need to check further if [[ "$helpTopic" == 'ping' ]]; then # If the ping topic is called, highlight the ping line in red echo -ne "\n\t\e[1;31m\033[1m-P, --ping DOMAIN\tPings domain from localhost with increasing sizes of packets up to 4KB.\033[0m"; else # Otherwise just display it normally echo -ne "\n\t-P, --ping DOMAIN\tPings domain from localhost with increasing sizes of packets up to 4KB."; fi; # No need to check further if [[ "$helpTopic" == 'dns' ]]; then # If the dns topic is called, highlight the dns line in red echo -ne "\n\t\e[1;31m\033[1m -D, --dns xx xx DOMAIN\tRuns a dig query against OpenNIC DNS specified (country code [required]) to get the specified DNS records (NS, A, MX, CNAME, TXT [if none, will use ANY]).\033[0m"; else # Otherwise just display it normally echo -ne "\n\t-D, --dns xx xx DOMAIN\tRuns a dig query against OpenNIC DNS specified (country code [required]) to get the specified DNS records (NS, A, MX, CNAME, TXT [if none, will use ANY])."; fi; # No need to check further if [[ "$helpTopic" == 'trace' ]]; then # If the trace topic is called, highlight the trace line in red echo -ne "\n\e[1;31m\033[1m\t-T, --trace DOMAIN\tRuns a trace on the domain, displays short output with number of hops (and IP of hop) and final answer.\033[0m"; else # Otherwise just display it normally echo -ne "\n\t-T, --trace DOMAIN\tRuns a trace on the domain, displays short output with number of hops (and IP of hop) and final answer."; fi; # No need to check further if [[ "$helpTopic" == 'whois' ]]; then # If the whois topic is called, highlight the whois line in red echo -ne "\n\e[1;31m\033[1m\t-W, --whois xx DOMAIN\tRuns a WHOIS lookup on the domain, and displays a short reply with only relevant information.\033[0m"; else # Otherwise just display it normally echo -ne "\n\t-W, --whois xx DOMAIN\tRuns a WHOIS lookup on the domain, and displays a short reply with only relevant information."; fi; # No need to check further echo -ne "\n\t-h, --help\t\tDisplays this help page.\n\nAll double dash switches and subsiquent switches are case insensitive.\n\ndomaintools is released under the GNU, original source by Jay.\n\n"; else # Otherwise the short help text is called for echo -e "\nUsage: domaintools [COMMAND]... [DOMAIN]...\nOutputs results of multiple queries on a given domain or IP.\n\nUse --help or -h for full help.\n"; fi; # No need to check further } # End of help function hostLookup () { # Host function if [[ "$logEnabled" == 'true' ]]; then # Check to see if logging is enabled echo -ne "Host lookup for domain: ${1,,} : " >> $logFile; # Write what happened to the log file, no need for full output date +"%H:%M:%S %Y/%m/%d" >> $logFile; # Append the date in a nicer format to the log file fi; # No need to check further if [[ "$debugEnabled" == 'true' ]]; then # Check to see if the debugger is on echo -n "" > $debugFile; # Blank the debugger file for i in "${countryList[@]}"; do # Loop through the DNS list array countryCode=$( echo ${i:0:2} ); # Give a freindly name to the first 2 characters of the array item (the country code) oDns=$( echo ${i:3} ); # Give a freindly name for the rest of the array item (excluding the :)(the IP address) echo -ne ":$countryCode $oDns \t" >> $debugFile; # Show which server is being queried host ${1,,} $oDns | egrep -i "has address" -m 1 >> $debugFile; # Outputs the result of each host lookup to debug file without display anything on screen. echo -ne "."; # Display an indicator that something is happening done # Stop looking in the array once it's reached the end echo -e "\nDone."; # Display a message to tell the user the command completed else # If the debugger is not enabled echo -e "\e[1;31m\033[1mQuerying OpenNIC for domain:\033[0m ${1,,}"; # display a nice highlighted message before the command for i in "${countryList[@]}"; do # Loop through the DNS list array countryCode=$( echo ${i:0:2} ); # Give a freindly name to the first 2 characters of the array item (the country code) oDns=$( echo ${i:3} ); # Give a freindly name for the rest of the array item (excluding the :)(the IP address) echo -ne ":$countryCode $oDns \t"; # Show which server is being queried host $1 $oDns | egrep -i "has address" -m 1; # For each item in the array, run the host function with the internally defined country code and DNS IP and the user specified domain / IP done # Stop looking in the array once it's reached the end fi; # No need to check further } # End of host function pingTest () { # Ping function if [[ "$logEnabled" == 'true' ]]; then # Check to see if logging is enabled echo -ne "Ping for domain: $1 : " >> $logFile; # Write what happened to the log file, no need for full output date +"%H:%M:%S %Y/%m/%d" >> $logFile; # Append the date in a nicer format to the log file fi; # No need to check further if [[ "$debugEnabled" == 'true' ]]; then # Check to see if the debugger is on echo -n "" > $debugFile; # Blank the debugger file for i in "${pingData[@]}"; do # Open up the ping data array (configured above) ping -c 1 -s $i $1 | grep "ttl" >> $debugFile; # Output the results to the debugger file without displaying on screen echo -ne "."; # Display an indicator that something is happening done # Finish looking up the array echo -e "\nDone."; # Display a message to tell the user the command completed exit; # Leave the script; else # If the debugger is not enabled echo -e "\e[1;31m\033[1mPinging domain:\033[0m $1"; # display a nice highlighted message before the command for i in "${pingData[@]}"; do # Open up the ping data array (configured above) echo -n ":"; ping -c 1 -s $i $1 | grep "ttl"; # For each item in the array, run the ping command with the array specified number of bytes on the user specified domain done # Finish looking up the array fi; # No need to check further } # End of ping function digLookup () { # Dig function if [[ "$logEnabled" == 'true' ]]; then # Check to see if logging is enabled echo -ne "Lookup for $2 records on $1 from global DNS $3 : " >> $logFile; # Write what happened to the log file, no need for full output date +"%H:%M:%S %Y/%m/%d" >> $logFile; # Append the date in a nicer format to the log file fi; # No need to check further if [[ "$debugEnabled" == 'true' ]]; then # Check to see if the debugger is on if [[ $4 == 2 ]]; then # Check if the record is set incorrectly echo "Invalid record type specified. Using ANY." > $debugFile; # Write the invalid record warning to the debug file else # If the record is valid echo "" > $debugFile; # Overwrite the debug file fi; # No need to check further dig $1 $2 @$3 +noall +answer >> $debugFile; # Output the results to the debugger (overwriting existing content) without displaying anything on screen else # If the debugger is not enabled if [[ $4 == 2 ]]; then # Check if the record is set incorrectly echo "Invalid record type defined. Using ANY."; # Display the invalid record warning fi; # No need to check further echo -e "\e[1;31m\033[1mLookup for\033[0m ${2^^} \e[1;31m\033[1mrecords on\033[0m ${1,,} \e[1;31m\033[1mfrom global DNS\033[0m ${3,,}"; # display a nice highlighted message before the command dig $1 $2 @$3 +noall +answer; # Run the dig command and output results to screen fi; # No need to check further } # End of dig function traceRoute () { # Trace function if [[ "$logEnabled" == 'true' ]]; then # Check to see if logging is enabled echo -ne "Trace route on ${1,,}" >> $logFile; # Write what happened to the log file, no need for full output date +"%H:%M:%S %Y/%m/%d" >> $logFile; # Append the date in a nicer format to the log file fi; # No need to check further if [[ "$debugEnabled" == 'true' ]]; then # Check to see if the debugger is on traceroute ${1,,} 64 > $debugFile; # Run a trace route on the domain specified else # If the debugger is not enabled echo -e "\e[1;31m\033[1mTrace route on\033[0m ${1,,}"; # display a nice highlighted message before the command traceroute ${1,,} 64; # Run a trace route on the domain specified fi; # No need to check further } # End of trace function whoisLookup () { # Whois function if [[ "$logEnabled" == 'true' ]]; then # Check to see if logging is enabled echo -ne "WHOIS query on $domainName : " >> $logFile; # Write what happened to the log file, no need for full output date +"%H:%M:%S %Y/%m/%d" >> $logFile; # Append the date in a nicer format to the log file fi; # No need to do anything special if logging is disabled if [[ "$debugEnabled" == 'true' ]]; then # Check to see if the debugger is on whois -H ${1,,} > $debugFile; # Output the results to the debugger (overwriting existing content) without displaying anything on screen else # If the debugger is not enabled echo -e "\e[1;31m\033[1mWHOIS Lookup for domain\033[0m ${1,,}"; # display a nice highlighted message before the command domainExtension=${1##*.}; ## Find the top level domain if [[ "$domainExtension" == 'uk' ]]; then # If the tld is a UK domain whois -H ${1,,} | egrep -i "tag|registered on|expiry date|last updated|no match|not found|not registered|no entries|error" | grep -vi "until"; # Get first run of whois and remove all irrelevant data whois -H ${1,,} | grep -iA 2 "name servers" | grep -vi "name servers"; # Get second run of whois and remove all irrelevant data else # If the tld is an international domain whois -H ${1,,} | egrep -i "created|last updated|expiration|name server|admin-c-email|admin email|no match|not found|not registered|no entries|error" | egrep -vi "notice|currently|reported"; # Display the relevant output of the whois fi; # No need to check further fi; # No need to check further } # End of whois function if [[ "$1" == '-H' || "${1,,}" == '--host' ]]; then # Check if the user specified the host switch if [ "$2" != "" ]; then # If the user defined a domain / IP domainName=${2,,}; # Give a freindly name to the user defined domain / IP hostLookup $domainName; # Run the host lookup function exit; # Leave script else # If nothing was entered after the host command showHelp full host; # Highlight the host line in the full help text exit; # Leave script fi; # No need to check further elif [[ "$1" == '-P' || "${1,,}" == '--ping' ]]; then # Check if the user specified the ping switch if [ "$2" != '' ]; then # Check to make sure the user entered something after the ping switch domainName=${2,,}; # Give a freindly name to the user specified domain / IP pingTest $domainName; # Run the ping function exit; # Leave script else # If nothing was entered after the ping switch showHelp full ping; # Highlight the ping command in the full help text exit; # Leave script fi; # No need to check further elif [[ "$1" == '-D' || "${1,,}" == '--dns' ]]; then # Check if the user specified the dns switch if [ "$2" != '' ]; then # If a country code is given userCountry=${2,,}; # Give a freindly name to the country code for i in "${countryList[@]}"; do # Look through the array of avaliable name servers (configured above) countryCode=$(echo ${i:0:2}); # Strip the IP's from the array and give it a new name if [[ "$userCountry" == "$countryCode" ]]; then # If the user entered country code matches that of one of the array items oDns=$(echo ${i:3}); # Define the name server to use as the IP address listed with that country code break; # Leave the loop (No need to check further) else # If the user didn't enter a valid country code, keep checking until the array is exahusted oDns="89.16.173.11"; # Define the name server as that of the UK OpenNIC name server fi; # No need to check further done # Stop looking in the array once it's reached the end if [[ "$3" != '' ]]; then # Check if a DNS record type to lookup was given userRecord=${3,,}; # Give a freindly name to the user entered record domainName=${4,,}; # Give a freindly name to the user entered domain / IP for i in ${dnsRecords[@]}; do # Look through the array of valid records (configured above) if [[ "$i" == "$userRecord" ]]; then # If the user record matches a valid record type if [[ $domainName != '' ]]; then # Check the user entered a domain after the record type usedRecord=${userRecord^^}; # Redefine the user record in all capitals for clarity on the dig output usedDomain=${domainName,,}; # Define the domain to use with the dig command to the same as the one the user entered recordSet=1; # Define the fact the record was set and is correct break; # Leave the for loop after the first successful lookup (no need to check further) else # If the user didn't actually enter a domain name showHelp full dns; # Highlight the dns line in the full help text exit; # Leave script fi; # No need to check further else # If the user record is not valid, keep checking until the array is exhuasted if [[ $domainName == '' ]]; then # If the user didn't enter a 4th paramater --dns 1 2 3 4, assume they didn't enter a record type (just a domain) usedRecord="ANY"; # Define the record as the default ANY record usedDomain=${userRecord,,}; # Define the domain as the 3rd paramater, which would be where the record normally is recordSet=0; # Define the fact the record was not set else # if the user did enter a record and domain, but the record was invalid usedRecord="ANY"; # Define the record as the default ANY record usedDomain=${domainName}; # Define the domain as the user entered domain recordSet=2; # Define the fact the record was incorrect fi; # No need to check further fi; # No need to check further done # Stop looking at each entry of the array digLookup $usedDomain $usedRecord $oDns $recordSet; # Run the dig command with the final inputs exit; # Leave script else # If the user didn't enter any other values after the dns switch showHelp full dns; # Highlight the dns line in the full help text exit; # Leave script fi; else # If the user didn't enter anything after the dns switch showHelp full dns; # Highlight dns line in the full help text exit; # Leave script fi; # No need to check further elif [[ "$1" == '-T' || "${1,,}" == '--trace' ]]; then # Check if the user specified the trace switch if [ "$2" != '' ]; then # Check to make sure the user entered *something* after the trace switch domainName=${2,,}; # Give a freindly name to the user entered domain / IP traceRoute $domainName; # Run the trace command exit; # Leave script else # If the user didn't enter anything after the whois switch showHelp full trace; # Highlight the whois line in the full help text exit; # Leave script fi; # No need to check further exit; # Leave script elif [[ "$1" == '-W' || "${1,,}" == '--whois' ]]; then # Check if the user specified the whois switch if [ "$2" != '' ]; then # Check to make sure the user entered *something* after the whois switch domainName=${2,,}; # Define the domain name entry whoisLookup $domainName; # Run the whois lookup on the specified domain exit; # Leave script else # If the user didn't enter anything after the whois switch showHelp full whois; # Highlight the whois line in the full help text exit; # Leave script fi; # No need to check further elif [[ "$1" == '-h' || "${1,,}" == '--help' ]]; then # If the first switch is for help showHelp full; # Show the full help text output but without any highlighting exit; # Leave script else # Catch all, if no recognised switch is called showMenu; # Just displays the short help message exit; # Leave script fi; # Main if statement closure exit; #No idea if it makes a difference, but looks nicer with it :)