Hello fellow DBAs, Oracle and Linux enthusiasts.
Today I'm going to share the script I use to "source" utility functions to the shell scripts I commonly use for my daily DBA tasks.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/ksh | |
########################### | |
## | |
## File: utility_functions.ksh | |
## | |
## Author: Jesus Sanchez (jsanchez.consultant@gmail.com) | |
## | |
## Changelog: | |
## 2015-05-14 Jesus Sanchez Created this script | |
## | |
###################################################################### | |
############### | |
## FUNCTIONS ## | |
############### | |
##################### | |
# Utility Functions # | |
##################### | |
########################## | |
# | |
# Function: continueQuestion | |
# | |
# Description: | |
# This function asks the user if all is good to continue | |
# | |
# Usage: continueQuestion | |
# | |
############################################## | |
function continueQuestion { | |
STEP=$1 | |
ANSWER="NONE" | |
while [[ $ANSWER != "y" && $ANSWER != "Y" && $ANSWER != "n" && $ANSWER != "N" ]] | |
do | |
if [[ $ANSWER != "NONE" ]] | |
then | |
print "[ATTENTION] Please enter \"y\" or \"n\" without the double quotes and press <ENTER>" | |
print " " | |
fi | |
print -n "[INPUT] Do you want to continue? (y/n) <ENTER> for [y]: " | |
read ANSWER | |
if [[ -z $ANSWER ]] | |
then | |
ANSWER="y" | |
fi | |
done | |
if [[ $ANSWER = "y" || $ANSWER = "Y" ]] | |
then | |
return 0 | |
elif [[ $ANSWER = "n" || $ANSWER = "N" ]] | |
then | |
exit -1 | |
fi | |
} | |
########################## | |
# | |
# Function name: debugPrint | |
# | |
# Description: | |
# This function will print debug messages if the | |
# main script was called with the -debug option | |
# | |
# Usage: debugPrint <double-quoted message> | |
# | |
#################### | |
function debugPrint { | |
if [[ $DEBUG -eq 1 ]] | |
then | |
TS=$(date +"%Y-%m-%d %H:%M:%S") | |
print "[DEBUG][${TS}] $1 " | |
fi | |
} | |
########################## | |
# | |
# Function name: msgPrint | |
# | |
# Description: | |
# This function will print debug messages if the | |
# main script was called with the -debug option | |
# | |
# Usage: | |
# msgPrint -<info|warning|error|critical|input> <double-quoted message> | |
# msgPrint -<blank|separator> | |
# | |
#################### | |
function msgPrint { | |
type="" | |
case $1 in | |
"-blank") type="BLANK";; | |
"-critical") type="CRITICAL";; | |
"-error") type="ERROR";; | |
"-debug") type="DEBUG" | |
if [[ $# -eq 2 ]] | |
then | |
shift | |
caller=$1 | |
fi;; | |
"-info") type="INFO";; | |
"-input") type="INPUT";; | |
"-notice") type="NOTICE";; | |
"-none") type="NONE";; | |
"-separator") type="SEPARATOR";; | |
"-title") type="TITLE";; | |
"-warning") type="WARNING";; | |
*) type="NONE" | |
esac | |
shift | |
message="$*" | |
if [[ ${type} = "BLANK" ]] | |
then | |
print " " | |
elif [[ ${type} = "DEBUG" ]] | |
then | |
if [[ $DEBUG -eq 1 ]] | |
then | |
ts=$(date +"%Y-%m-%d %H:%M:%S") | |
print "[$type][$ts][$caller] $message " | |
fi | |
elif [[ ${type} = "INPUT" ]] | |
then | |
print -n "[$type] $message: " | |
elif [[ ${type} = "SEPARATOR" ]] | |
then | |
print "----------------------------------------------" | |
elif [[ ${type} = "TITLE" ]] | |
then | |
SPLITTER="=================================================" | |
print " " | |
print "$SPLITTER" | |
print "$message" | |
print "$SPLITTER" | |
print " " | |
elif [[ ${type} = "NONE" ]] | |
then | |
print "[ $message ]" | |
else | |
print "[$type] $message" | |
fi | |
} | |
########################## | |
# | |
# Function name: getArgs | |
# | |
# Description: | |
# This function provides the getopts functionality | |
# while allowing the use of long operations and list of parameters. | |
# in the case of a list of arguments for only one option, this list | |
# will be returned as a single-space-separated list in one single string. | |
# | |
# Pre-reqs: | |
# None | |
# | |
# Output: | |
# GA_OPTION variable will hold the current option | |
# GA_VALUE variable will hold the value (or list of values) associated | |
# with the current option | |
# | |
# Usage: | |
# You have to source the function in order to be able to access the GA_OPTIONS | |
# and GA_VALUES variables | |
# . getArgs $* | |
# | |
#################### | |
function getArgs { | |
# Variables to return the values out of the function | |
typeset -a GA_OPTIONS | |
typeset -a GA_VALUES | |
# Checking for number of arguments | |
if [[ -z $1 ]] | |
then | |
msgPrint -warning "No arguments found" | |
msgPrint -info "Please call this function as follows: . getArgs \$*" | |
exit 0 | |
fi | |
# Grab the dash | |
dash=$(echo $1 | grep "-") | |
# Looking for short (-) or long (--) options | |
isOption=$(expr index "$dash" "-") | |
# Initialize the counter | |
counter=0 | |
# Loop while there are arguments left | |
while [[ $# -gt 0 ]] | |
do | |
if [[ $dash && $isOption -eq 1 ]] | |
then | |
(( counter+=1 )) | |
GA_OPTIONS[$counter]=$1 | |
shift | |
else | |
if [[ -z ${GA_VALUES[$counter]} ]] | |
then | |
GA_VALUES[$counter]=$1 | |
else | |
GA_VALUES[$counter]="${GA_VALUES[$counter]} $1" | |
fi | |
shift | |
fi | |
dash=$(echo $1 | grep "-") | |
isOption=$(expr index "$dash" "-") | |
done | |
# Make the variables available to the main algorithm | |
export GA_OPTIONS | |
export GA_VALUES | |
msgPrint -debug "Please check the GA_OPTIONS and GA_VALUES arrays for options and arguments" | |
# Exit with success | |
return 0 | |
} | |
########################## | |
# | |
# Function name: setupLogs | |
# | |
# Description: | |
# This function will setup alog redirection pipe | |
# that will allow to write to console as well as to a logfile. | |
# | |
# Pre-reqs: | |
# Use the variable $LOGFILE in the main algorythm with | |
# full path and file name. | |
# | |
# Usage: | |
# setupLog <start|stop> <LOGFILE> | |
# | |
#################### | |
function setupLogs { | |
if [[ $1 = "start" ]] | |
then | |
# set up redirects | |
exec 3>&1 4>&2 | |
FIFO=/tmp/fifo.$$ | |
[[ -e $FIFO ]] || mkfifo $FIFO | |
if [[ -e $LOGFILE ]] | |
then | |
tee -a $LOGFILE < $FIFO >&3 & | |
else | |
tee $LOGFILE < $FIFO >&3 & | |
fi | |
PID=$! | |
exec > $FIFO 2>&1 | |
return 0 | |
elif [[ $1 = "stop" ]] | |
then | |
PIDLIST="" | |
for PROCID in $(ps -ef | grep -v grep | grep "$$" | grep tee | tr -s [:space:] | cut -d" " -f2) | |
do | |
if [[ -z $(echo $PROCID | grep tee |tr -d [:space:]) && -z $PIDLIST ]] | |
then | |
PIDLIST="$PROCID" | |
else | |
PIDLIST="$PIDLIST $PROCID" | |
fi | |
done | |
msgPrint -debug "PIDLIST: $PIDLIST" | |
exec 1>&3 2>&4 3>&- 4>&- | |
wait $PIDLIST | |
rm -f /tmp/fifo.$$ && return 0 | |
fi | |
} | |
export FIFO | |
########################## | |
# | |
# Function name: setupProfiling | |
# | |
# Description: | |
# This function will setup a log where timestamps will | |
# be kept for calculating profiling information | |
# | |
# Pre-reqs: | |
# None | |
# | |
# Usage: | |
# setupProfiling <start|stop> <SCRIPT|FUNCTION NAME> | |
# | |
#################### | |
function profiling { | |
caller=${2} | |
profileLog=/tmp/${caller}_$$.tmp | |
if [[ $1 == "start" || $1 == "START" ]] | |
then | |
touch $profileLog | |
TS=$(date +"%s") | |
echo "$2:START:$TS" >> $profileLog | |
return 0 | |
elif [[ $1 == "stop" || $1 == "STOP" ]] | |
then | |
TS=$(date +"%s") | |
echo "$2:STOP:$TS" >> $profileLog | |
RT=0 | |
RTH=0 | |
RTM=0 | |
RTS=0 | |
cat $profileLog | |
STARTTS=$(cat $profileLog | grep START | cut -d":" -f3) | |
ENDTS=$(cat $profileLog | grep STOP | cut -d":" -f3) | |
RT=$(( ENDTS-STARTTS )) | |
if [[ $RT -lt 60 ]] | |
then | |
RTS=$RT | |
elif [[ $RT -lt 3600 ]] | |
then | |
RTM=$( echo $RT / 60 | bc) | |
RT=$( echo $RT % 60 | bc ) | |
RTS=$RT | |
else | |
RTH=$( echo $RT / 3600 | bc) | |
RT=$(( $RT % 3600 )) | |
RTM=$( echo $RT / 60 | bc) | |
RT=$( echo $RT % 60 | bc ) | |
RTS=$RT | |
fi | |
rm -f $profileLog | |
return 0 | |
fi | |
} |
Let's add some explanation:
- continueQuestion
- This function is a simple "Continue? (y/n)" question. As this is used a lot in interactive scripts, seemed like a good idea for me to add it to the utility functions script.
- debugPrint
- For debugging, it adds the timestamp prior to the message. Allows you to keep track of what, where and when something is happening.
- msgPrint
- Allows you to format in several ways the output that you want to send to console/log file.
I hope you find this useful and makes your job better!
No comments:
Post a Comment