Advertisement
spikeysnack

shortopts

Nov 11th, 2016
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 4.97 KB | None | 0 0
  1. #!/bin/bash
  2. # shortops
  3.  
  4. # shorten options and resolve conflicts
  5. # validate with getopt
  6. # then parse with getopts
  7. # this utilizes the set function to work
  8. # with the bash poisitional parameters.
  9. # It is easier to shorten the options because
  10. # getopts only does short options.
  11. # chris Reid <spikeysnack@gmail.com>
  12.  
  13. # Explanation for tools:
  14. #    getopt is a c utility that comes with most linux and bsd distros.
  15. #           It parses short and long options and rearranges them puutinjg the non-options at the end.
  16.  
  17. #    getopts is built in to bash and is simple and robust, but can not handle long options
  18.  
  19. #    conflicts is a functional attempt to apply a logic rule filter to a set of options
  20. #              without horrendous nested if then ladders of doom.
  21.  
  22. # The ugly part is the conversions from lists to arrays and back.
  23. #     It is tedious and fraught with danger. (The Quoting!)
  24. #     so here is a toy program illustrating how to do such things.
  25.  
  26.  
  27. # The set built-in is the only way to set positional parameters.
  28. # so set them if they are not set.
  29. default_params="John Dog --full --good-time --help Obama -i -j -k one 2 3 here we go"
  30. default_params2="Snoopy says -j --good-time --help Obama -i -j   one 2 3 here we go"
  31.  
  32. [[ -z ${@} ]] && set -- "${@}" "${default_params}"
  33.  
  34. options="fgh:ijkGBb"
  35. long_options="full,good,bad,help,info,joking,kill,good-times,bad-times,good-beer"
  36.  
  37.  
  38. # balk on conflicting options
  39. conflicts()
  40. {
  41.     argslist="${@}"
  42.  
  43.     # the "easy way" ( set/not set )  -- works good
  44.  
  45.     local  f l h i j k G B b   # private option vars defined but not set
  46.  
  47.     # regex hastack =~ needle ; found sets var
  48.  
  49.     [[ "${argslist}" =~ "-f" ]] && f=1
  50.     [[ "${argslist}" =~ "-h" ]] && h=1
  51.     [[ "${argslist}" =~ "-i" ]] && i=1
  52.     [[ "${argslist}" =~ "-j" ]] && i=1
  53.     [[ "${argslist}" =~ "-k" ]] && k=1
  54.     [[ "${argslist}" =~ "-G" ]] && G=1
  55.     [[ "${argslist}" =~ "-B" ]] && B=1
  56.     [[ "${argslist}" =~ "-b" ]] && b=1
  57.    
  58.     let "total = f + h + i + j + k + G + B + b" # how many options?
  59.  
  60.     if [[ $total -gt 1 ]] ; then  # only one option == no conflicts
  61.    
  62.     # idempotent options  -- these each overide any other flags
  63.     [[ $h || $j || $k ]]  && echo "conflict:  h, j, and  k are idempotent options" && exit
  64.        
  65.     # conflicting options
  66.     [[ $f ]] && [[ $G || $b ]] && echo "conflict:  with -f [G b]" && exit
  67.     [[ $G ]] && [[ $B ]]       && echo "conflict:  with -G [B]" && exit
  68.     [[ $k ]] && [[ $b ]]       && echo "conflict:  with -k [b]" && exit
  69.        
  70.     fi
  71. }
  72.  
  73.  
  74.  
  75. shorten_opts()
  76. {
  77.     local options="${1}"
  78.     shift
  79.     local args="${@}"
  80.  
  81.     i=0
  82.     until [ "$((i=$i+1))" -gt "$#" ]
  83.     do
  84.     case "$1"  in
  85.         #explicit
  86.         #       --full) set -- "$@" "-f"  ;;
  87.         #       --help) set -- "$@" "-h"  ;;
  88.             --good-times) set -- "$@" "-t"  ;; # (substitute string )
  89.             --good-beer)  set -- "$@" "-b"   ;;
  90.             --bad-times)  set -- "$@" "-B"   ;;
  91.        
  92.         #implicit
  93.         --*)  s="${1:1:2}"; set -- "$@" "${s}"  ;; # (--full-option  ==> -f)
  94.         #everything else
  95.         *)      set -- "$@" "$1"  ;; # pass unchanged
  96.     esac; shift;
  97.     done
  98.    
  99.     OPTS=$( getopt -u  -n "${0}" -o "${options}"  -- ${@} )
  100.  
  101.  
  102.     echo "${OPTS}"
  103.  
  104. }
  105.  
  106. #set -- "$@" "John Dog --full --good --help Obama -i -j -k one 2 3 here we go"
  107.  
  108. echo "original opts:  ${@}"
  109.  
  110. shortopts=$(shorten_opts "${options}" ${@})
  111. shortopts=( ${shortopts[@]} )
  112.  
  113. #declare | grep shortopts >&2
  114.  
  115. echo "shortened opts: ${shortopts[@]}  (${#shortopts[@]})"
  116.  
  117. #set positional parameters  ${shortopts[@]}  ==> ${@}
  118. set -- "${shortopts[@]}"
  119.  
  120. # options="bfgh:ijkGB"
  121.  
  122.  
  123. # check for conflicts among options
  124. conflicts "${@}"
  125.  
  126.  
  127. while getopts  "${options}" OPTION
  128. do
  129.     case $OPTION  in
  130.  
  131.         b)  BAD=1  ;;
  132.  
  133.         f)  FULL=1 ;;
  134.        
  135.         g)  GOOD=1  ;;
  136.        
  137.         h)  HELP=1 ; president="${OPTARG}" ;;
  138.        
  139.         i)  INFO=1  ;;
  140.        
  141.         j)  JOKE=1  ;;
  142.  
  143.         k)  KILL=1  ;;
  144.        
  145.         G)  GOODTIMES=1 ;;
  146.        
  147.         B) BADTIMES=1 ;;
  148.        
  149.         ?) echo "OOPS" ; exit ;;
  150.     esac;
  151.    
  152. #   shift;
  153. done
  154.  
  155.  
  156. #set --  "${OPTIND}" 1
  157.  
  158. printf  "options set:\n"
  159. [[ ${BAD}  ]] && echo -e "\tBAD"
  160. [[ ${FULL} ]] && echo -e "\tFULL"
  161. [[ ${GOOD} ]] && echo -e "\tGOOD"
  162. [[ ${HELP} ]] && echo -e "\tHELP  ${president}"
  163. [[ ${INFO} ]] && echo -e "\tINFO"
  164. [[ ${JOKE} ]] && echo -e "\tJOKE"
  165. [[ ${KILL} ]] && echo -e "\tKILL"
  166. [[ ${GOODTIMES} ]] &&  echo -e "\tGOOD TIMES"
  167. [[ ${GOODBEER} ]] && echo -e "\tGOOD BEER"
  168. [[ ${BADTIMES} ]] && echo -e "\tBAD TIMES"
  169.  
  170.  
  171. #[[ ${@} ]] && echo "\${@} = ${@}"
  172.  
  173. if [[ $INFO ]] ;then
  174.     n=0
  175.     for arg in  ${@}
  176.     do
  177.     printf "[%d](%s)\t"  $n "${arg}"
  178.    
  179.     [ $n -gt 0 ] && [ $((n % 5))  -eq 0 ] && printf "\n"
  180.    
  181.     ((n = n +1))
  182.    
  183.     done
  184.     printf "\n"
  185.    
  186.     printf "current arg:\t%s\n"   "${!OPTIND}"
  187. fi
  188.  
  189. if [[ $JOKE ]] ; then
  190.  
  191.     Q="(D) Jul jnf gur Mra ohqquvfg fb qvffngvfsvrq?\n"
  192.     echo  -e ${Q} | rot13
  193.    
  194.     read  enter
  195.    
  196.     A="(N) Orpnhfr abguvat jnf jung ur jnagrq.\n"
  197.     echo  -e ${A} | rot13
  198. fi
  199.  
  200. #end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement