Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # shortops
- # shorten options and resolve conflicts
- # validate with getopt
- # then parse with getopts
- # this utilizes the set function to work
- # with the bash poisitional parameters.
- # It is easier to shorten the options because
- # getopts only does short options.
- # chris Reid <spikeysnack@gmail.com>
- # Explanation for tools:
- # getopt is a c utility that comes with most linux and bsd distros.
- # It parses short and long options and rearranges them puutinjg the non-options at the end.
- # getopts is built in to bash and is simple and robust, but can not handle long options
- # conflicts is a functional attempt to apply a logic rule filter to a set of options
- # without horrendous nested if then ladders of doom.
- # The ugly part is the conversions from lists to arrays and back.
- # It is tedious and fraught with danger. (The Quoting!)
- # so here is a toy program illustrating how to do such things.
- # The set built-in is the only way to set positional parameters.
- # so set them if they are not set.
- default_params="John Dog --full --good-time --help Obama -i -j -k one 2 3 here we go"
- default_params2="Snoopy says -j --good-time --help Obama -i -j one 2 3 here we go"
- [[ -z ${@} ]] && set -- "${@}" "${default_params}"
- options="fgh:ijkGBb"
- long_options="full,good,bad,help,info,joking,kill,good-times,bad-times,good-beer"
- # balk on conflicting options
- conflicts()
- {
- argslist="${@}"
- # the "easy way" ( set/not set ) -- works good
- local f l h i j k G B b # private option vars defined but not set
- # regex hastack =~ needle ; found sets var
- [[ "${argslist}" =~ "-f" ]] && f=1
- [[ "${argslist}" =~ "-h" ]] && h=1
- [[ "${argslist}" =~ "-i" ]] && i=1
- [[ "${argslist}" =~ "-j" ]] && i=1
- [[ "${argslist}" =~ "-k" ]] && k=1
- [[ "${argslist}" =~ "-G" ]] && G=1
- [[ "${argslist}" =~ "-B" ]] && B=1
- [[ "${argslist}" =~ "-b" ]] && b=1
- let "total = f + h + i + j + k + G + B + b" # how many options?
- if [[ $total -gt 1 ]] ; then # only one option == no conflicts
- # idempotent options -- these each overide any other flags
- [[ $h || $j || $k ]] && echo "conflict: h, j, and k are idempotent options" && exit
- # conflicting options
- [[ $f ]] && [[ $G || $b ]] && echo "conflict: with -f [G b]" && exit
- [[ $G ]] && [[ $B ]] && echo "conflict: with -G [B]" && exit
- [[ $k ]] && [[ $b ]] && echo "conflict: with -k [b]" && exit
- fi
- }
- shorten_opts()
- {
- local options="${1}"
- shift
- local args="${@}"
- i=0
- until [ "$((i=$i+1))" -gt "$#" ]
- do
- case "$1" in
- #explicit
- # --full) set -- "$@" "-f" ;;
- # --help) set -- "$@" "-h" ;;
- --good-times) set -- "$@" "-t" ;; # (substitute string )
- --good-beer) set -- "$@" "-b" ;;
- --bad-times) set -- "$@" "-B" ;;
- #implicit
- --*) s="${1:1:2}"; set -- "$@" "${s}" ;; # (--full-option ==> -f)
- #everything else
- *) set -- "$@" "$1" ;; # pass unchanged
- esac; shift;
- done
- OPTS=$( getopt -u -n "${0}" -o "${options}" -- ${@} )
- echo "${OPTS}"
- }
- #set -- "$@" "John Dog --full --good --help Obama -i -j -k one 2 3 here we go"
- echo "original opts: ${@}"
- shortopts=$(shorten_opts "${options}" ${@})
- shortopts=( ${shortopts[@]} )
- #declare | grep shortopts >&2
- echo "shortened opts: ${shortopts[@]} (${#shortopts[@]})"
- #set positional parameters ${shortopts[@]} ==> ${@}
- set -- "${shortopts[@]}"
- # options="bfgh:ijkGB"
- # check for conflicts among options
- conflicts "${@}"
- while getopts "${options}" OPTION
- do
- case $OPTION in
- b) BAD=1 ;;
- f) FULL=1 ;;
- g) GOOD=1 ;;
- h) HELP=1 ; president="${OPTARG}" ;;
- i) INFO=1 ;;
- j) JOKE=1 ;;
- k) KILL=1 ;;
- G) GOODTIMES=1 ;;
- B) BADTIMES=1 ;;
- ?) echo "OOPS" ; exit ;;
- esac;
- # shift;
- done
- #set -- "${OPTIND}" 1
- printf "options set:\n"
- [[ ${BAD} ]] && echo -e "\tBAD"
- [[ ${FULL} ]] && echo -e "\tFULL"
- [[ ${GOOD} ]] && echo -e "\tGOOD"
- [[ ${HELP} ]] && echo -e "\tHELP ${president}"
- [[ ${INFO} ]] && echo -e "\tINFO"
- [[ ${JOKE} ]] && echo -e "\tJOKE"
- [[ ${KILL} ]] && echo -e "\tKILL"
- [[ ${GOODTIMES} ]] && echo -e "\tGOOD TIMES"
- [[ ${GOODBEER} ]] && echo -e "\tGOOD BEER"
- [[ ${BADTIMES} ]] && echo -e "\tBAD TIMES"
- #[[ ${@} ]] && echo "\${@} = ${@}"
- if [[ $INFO ]] ;then
- n=0
- for arg in ${@}
- do
- printf "[%d](%s)\t" $n "${arg}"
- [ $n -gt 0 ] && [ $((n % 5)) -eq 0 ] && printf "\n"
- ((n = n +1))
- done
- printf "\n"
- printf "current arg:\t%s\n" "${!OPTIND}"
- fi
- if [[ $JOKE ]] ; then
- Q="(D) Jul jnf gur Mra ohqquvfg fb qvffngvfsvrq?\n"
- echo -e ${Q} | rot13
- read enter
- A="(N) Orpnhfr abguvat jnf jung ur jnagrq.\n"
- echo -e ${A} | rot13
- fi
- #end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement