Sunday, November 1, 2009

BASH: Using untyped variable to get unlimited parameter

I have been working a backup script at work that support MySQL, PostgreSQL and file using mysql_dump, pg_dump and duplicity commands. Since the script will be running parallel, the script will be calling up itself a lot, I need a better parameter parsing. And I absolutely do not want to use 100 lines of code to do such simple task. It will be so hard to maintain. And when I was trying to improve my parameter parsing, I found something called "untyped variable". I am not sure if it's a proper name.

Anyway, the whole point of doing this is: you do not have to use a lot of if conditions or case to sort variable one by one. You can just put the variable name in a loop, and it will parse out all recognized variable names.

I am using 'eval' to assign the values into variables. I was originally using 'export'. And I know there is actually some other way to do some, something like $($OPT)=$FIELDS, but somehow it didn't work for me. :-(


Using 'eval' to assign.
eval $OPT=$FIELDS


Parsing all variables and values

# Define all acceptable variable names here
ALL_OPT=(Type Host Pass User DB Table MaxTry BackupDir Src Dst Port sshUser Period dbExtra)

for WORD in $@ ; do # $WORD is the name of variable,
for OPT in ${ALL_OPT[*]} ; do # Check if I have the option in the list
FIELDS=""
case $WORD in
$OPT=?*) # To make sure it has '=' and at least one character after '='
FIELDS=${WORD:`echo ${#OPT}+1 |bc`} # grap the value
eval $OPT=$FIELDS # Assign the variable to
echo " export $OPT $FIELDS"
;;
Report)
echo "calling up Report"
bkReport
break
;;
esac
[ "$FIELDS" == "" ] || break # no value at all
done
done


Display all variable names and value

for OPT in ${ALL_OPT[*]} ; do
eval aaa=\$$OPT
echo $OPT = $aaa
done



Calling up the function

# Define all function names, which is the accepted variables value in first variable in ALL_OPT
ALL_TYPE=(Mysql File MySql Redmine)
[ $Type == "NULL" ] || for TypeCHK in ${ALL_TYPE[*]} ; do
if [ $Type == $TypeCHK ] ; then
ChkPeriod $Period
[ $? == 0 ] && bk$Type # Of course, you have to have the function, e.g: 'bkFile'.
fi
done


All codes

No comments: