I have written a lot of ksh scripts as a DBA. I have always wanted to process the script parameters as keyword pairs (like Oracle commands allow). But I hate to give up allowing a simple parameter or two in a specified order. The following script actually assigns values to parameters based on either keywords or in a default order. You can even mix keywords pairs with the default order.
eval lets me assign the keyword pairs. I love that. Notice that debug=TRUE is used in the sample. Even though debug is not specified in the order list, debug can be set on the command line. Any keyword=value on the command line will set the environment variable keyword to the specified value.
We also need to work with some ksh arrays. I tried hard to delete the keyword from parmNames but could not make that work. I used a new array.
Even if the script is overkill for my little scripts, it uses a variety of techniques which might be interesting.
In this example usage, the default order of parameters is x y z. But y is set explicitly as a keyword pair in the first position. It is removed from the ordered list and x and z are then set to the next two parameters. And debugging (yes, it is pitiful) is turned on with debug=TRUE. The debugging text 0: x 0 and 2: z 0 shows that x and z are not keyword pairs while y (1: y 1) is a keyword pair. Y is removed from the ordered parameter list leaving x and z to be set. Argument 2 (2nd position on the command line) is set to x, and Argument 3 on the command line is set to z. The final debugging text dumps x, y, and as 2 1 3.
Sample call
Code:
#! /bin/ksh
#set -x
main() {
# Create a list with the default option order
typeset -a parmNames=(x y z)
typeset -a keepList=()
allArgs=”$@”
processCommandLine
}
processCommandLine() {
# set allArgs to the command line parameters with allArgs=”$@”
# And set pramNames to an ordered list of allowed parameters with parmNames=(x y z)
# Command line parameters are expected to be in the format x=123, y=ABC, 123 or ABC
# Spaces may not be tolerated even when quoted as subsequent commands may remove the quotes.
# The default behavior is to create variables from the argument list in the order specified in parmNames
# But keyword pairs x=1, y=abc, z=1.2 can be embedded in the argument list as well
# If you mix keyword pairs with ordered parameters, the parameters will be populated from the non-keyword-pair values
# in the order specified once all keyword pair parameters are removed.
# Check all command line arguments to see if debug is set.
for arg in $allArgs
do
debugCheck=`echo $arg | grep -i debug= | wc -l`
if [ debugCheck -gt 0 ]
then
debug=`echo $arg | cut -d’=’ -f2`
typeset -u debug
else
debug=FALSE
fi
done
if [ $debug != FALSE ]
then
echo “debugging $debug”
echo Looping over parms…
fi
i=0
# Look over all the parameter names to find those that are part of a keyword pair on the command line (must have an = sign and text on either side of the = sign.
for parmName in ${parmNames[*]}
do
# Check if the command line contains the current parameter name
specifiedCount=`echo $allArgs | grep “${parmName}=” | wc -l`
if [ $debug != FALSE ]
then
echo $i: $parmName $specifiedCount
fi
# If the current parameter name is not part of a keyword pair, keep it as an ordered parameter.
if [ specifiedCount -eq 0 ]
then
keepList+=(${parmName})
fi
i=`expr $i + 1`
done
if [ $debug != FALSE ]
then
echo Ordered parameter list is ${keepList[@]} after removing keyword pairs.
fi
# Restart the index on the command line arguments
i=0
for arg in $allArgs
do
if [ $debug != FALSE ]
then
echo processing $arg …
fi
keyword_check=`echo $arg | awk -F= ‘{print NF}’ -`
if [ $debug != FALSE ]
then
echo keyword check: $keyword_check
fi
if [ $keyword_check -gt 1 ]
then
# Assign the option
eval $arg
else
if [ $debug != FALSE ]
then
echo argument: $arg assign to parmName ${keepList[$i]}
fi
eval ${keepList[$i]}=$arg
i=`expr $i + 1`
fi
done
if [ $debug != FALSE ]
then
for parmName in ${parmNames[@]}
do
eval echo \$$parmName
done
fi
}
# start script
main “$@”
$ . ./test.ksh y=1 2 3 debug=TRUE
debugging TRUE
Looping over parms…
0: x 0
1: y 1
2: z 0
Ordered parameter list is x z after removing keyword pairs.
processing y=1 …
keyword check: 2
processing 2 …
keyword check: 1
argument: 2 assign to parmName x
processing 3 …
keyword check: 1
argument: 3 assign to parmName z
processing debug=TRUE …
keyword check: 2
2
1
3
I use allArgs instead of continuing to use $@ throughout the script as some commands replace $@.
Bye.