In shell, How do I efficiently process arguments passed to a function to invoke other programs without using too many conditional statements?
I don't have much practical programming experience. I wrote a function in shell script to take parameters based on whose values an external program is invoked with other parameters. (the program name is passed as a parameter to the function, $1 in this case).
Somehow I find this code shitty and would like to reduce the lines and make it more efficient. I feel like there are too many conditions here and there 开发者_运维技巧might be an easier way to do this. Any ideas? There has to be a better way to do this. Thanks.
Code is here
You can build the argument list as an array, with separate conditionals for each variable part of the list (rather than nested conditionals as you have). This is very similar to Roland Illig's answer, except that using an array rather than a text variable avoids possible problems with funny characters (like spaces) in arguments (see BashFAQ #050) -- it's probably not needed here, but I prefer to do it the safe way to avoid surprises later. Also, note that I've assumed the arguments must be in a certain order -- if -disp
can go before `refresh
, then the "all versions" parts can all be put together at the beginning.
# Build the argument list, depending on a variety of conditions
arg_list=("-res" "$2" "$3") # all versions start this way
if [ "$7" = "allresolutions" ]; then
# allresolutions include the refresh rate parameter to be passed
arg_list+=("-refresh" "$4")
fi
arg_list+=("-disp" "$5") # all versions need the disp value
if [ "$6" = "nooptions" ]; then
: # nothing to add
elif [ "$6" = "vcaa" ]; then
arg_list+=("-vcaa" "5")
elif [ "$6" = "fsaa" ]; then
arg_list+=("-fsaa" "4")
elif [ "$6" = "vcfsaa" ]; then
arg_list+=("-vcaa" "5" "-fsaa" "4")
fi
if [ "$1" != "gears" ]; then
# ctree has time-to-run passed as parameter to account for suitable time for
# logging fps score. If bubble fps capture strategy is different from ctree,
# then this if statement has to be modified accordingly
arg_list+=("-sec" "$8")
fi
# Now actually run it
./"$1" "${arg_list[@]}" &>> ~/fps.log
Instead of the repeated inner "if … elif … fi" you can do this part of the argument processing once and save it in a variable (here: options).
case $6 in
nooptions) options="";;
vcaa) options="-vcaa 5";;
fsaa) options="-fsaa 4";;
vcfsaa) options="-vcaa 5 -fsaa 4";;
esac
...
./$1 -res $2 $3 -refresh $4 -disp $5 $options -sec $8
You could use getopts (see example) if you process that large number of arguments.
精彩评论