Question
Say, I have a script that gets called with this line:
or this one:
What's the accepted way of parsing this such that in each case (or some combination of the two) $v, $f, and $d will all be set to true and $outFile will be equal to /fizz/someOtherFile ?
How-To
Preferred Method: Using straight bash without getopt[s]
I originally answered the question as the OP asked. This Q/A is getting a lot of attention, so I should also offer the non-magic way to do this. I'm going to expand upon guneysus's answer to fix the nasty sed and include Tobias Kienzler's suggestion. Two of the most common ways to pass key value pair arguments are:
Straight Bash Space Separated
- myscript.sh
- #!/bin/sh
- # some arguments don't have a corresponding value to go with it such as
- # in the --default example).
- # note: if this is et to -gt 0 the /etc/hosts part is not recongnized
- while [[ $# -gt 1 ]]
- do
- key="$1"
- case $key in
- -e|--extension)
- EXTENSION="$2"
- shift # past argument
- ;;
- -s|--searchpath)
- SEARCHPATH="$2"
- shift
- ;;
- -l|--lib)
- LIBPATH="$2"
- shift
- ;;
- --default)
- DEFAULT=YES
- ;;
- *)
- # Unknown option
- ;;
- esac
- shift # past argument or value
- done
- echo "File extension=${EXTENSION}"
- echo "Search path=${SEARCHPATH}"
- echo "Library path=${LIBPATH}"
- if [[ -n $1 ]]; then
- echo "Last line of file specified as non-opt/last argument: $1"
- fi
Straight Bash Equals Separated
- myscript2.sh
- #!/bin/sh
- DEFAULT=NO
- for i in "$@"
- do
- case $1 in
- -e=*|--extension=*)
- EXTENSION="${i#*=}"
- shift # pass argument = value
- ;;
- -s=*|--search=*)
- SEARCHPATH="${i#*=}"
- shift
- ;;
- -l=*|--lib=*)
- LIBPATH="${i#*=}"
- shift
- ;;
- --default)
- DEFAULT=YES
- shift
- ;;
- *)
- # Unknown option
- ;;
- esac
- done
- echo "File extension=${EXTENSION}"
- echo "Search path=${SEARCHPATH}"
- echo "Library path=${LIBPATH}"
- echo "Is Default? ${DEFAULT}"
- if [[ -n $1 ]]; then
- echo "Last line of file specified as non-opt/last argument: $1"
- fi
Using getopt[s]
from: http://mywiki.wooledge.org/BashFAQ/035#getopts
Never use getopt(1). getopt cannot handle empty arguments strings, or arguments with embedded whitespace. Please forget that it ever existed. The POSIX shell (and others) offer getopts which is safe to use instead. Here is a simplistic getopts example:
- myscript3.sh
- #!/bin/sh
- # A POSIX variable
- OPTION=1 # Reset in case getopts has been used previous in the shell
- # Initialize our own variables:
- output_file=""
- verbose=0
- function show_help(){
- echo "Show help here!"
- }
- while getopts "h?vf:" opt; do
- case "$opt" in
- h|\?)
- show_help
- exit 0
- ;;
- v) verbose=1
- ;;
- f) output_file=$OPTARG
- ;;
- esac
- done
- shift $((OPTIND-1))
- [ "$1" == '--' ] && shift
- echo "verbose=$verbose, output_file='$output_file', Leftovers: $@"
- # End of file
The advantages of getopts are:
The disadvantage of getopts is that it can only handle short options (-h, not --help) without trickery. There is a getopts tutorial which explains what all of the syntax and variables mean. In bash, there is also help getopts, which might be informative.
沒有留言:
張貼留言