1

Have written two ways, trying to parse short and long options by hand. The first is complicated with the use of IFS=" =". Perhaps set -- $* is not necessary.

rando ()
{
 IFSPREV="$IFS"  # Save IFS (splits arguments on whitespace by default)
 IFS=" ="        # Split arguments on " " and "="
 set -- $*       # Set positional parameters to command line arguments
 IFS="$IFSPREV"  # Set original IFS
 
 local  iarg=0  narg="$#"
 
 while (( narg > 0 )); do

   opt="$1"
   iarg=$(( iarg + 1 ))

   case $opt in
     ("-s"|"--src"|"--source")  src="$2" ; shift 2 ;;
     ("-d"|"--dst"|"--destin")  dst="$2" ; shift 2 ;;
     ("--")  shift 1 ; break ;;
     ("-"*)  printf '%s\n' "Unknown option: $1" ; shift 1 ;;
     (*) shift 1 ; break ;;
   esac

 done
}

And here is the other, but I also want to split on = for long-options.

rando ()
{
  PARAMS=""
  while (( "$#" )); do
  case "$1" in
    ("-s"|"--src"|"--source")
      if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
        src="$2"
        shift 2
      else
        echo "Error: Argument for $1 is missing" >&2
        exit 1
      fi
      ;;
    ("-d"|"--dst"|"--destin")
      if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
        dst="$2"
        shift 2
      else
        echo "Error: Argument for $1 is missing" >&2
        exit 1
      fi
      ;;
    -*|--*=) # unsupported flags
      echo "Error: Unsupported flag $1" >&2
      exit 1
      ;;
    *) # preserve positional arguments
      PARAMS="$PARAMS $1"
      shift
      ;;
    esac
  done
}
Angio
  • 57
  • 1
  • 5
  • 1
    Out of curiosity, why are you implementing this by hand? Using [`getopt`](https://stackoverflow.com/a/29754866/68587) will save you a lot of work and will handle edge cases much better. For example, your code doesn't handle arguments with spaces properly, and it doesn't allow short options to be combined a la `rm -rf`. – John Kugelman Sep 07 '21 at 01:34
  • People have told me that I should not use `getopts` because it is not portable. And `getopt` handles only short options, thusly too simplistic. Asked the Gnu Bash Maintainer, who told me that he does not know how to implement long-options and optional values to arguments. Also posix standard says that long options are not a requirement. – Angio Sep 07 '21 at 02:19
  • Let's handle one thing at a time, without worrying about spaces and option combination. Regarding option combination, we can think that combination for options that do not take values is good. Myself, I do not like options with values that do not use a space after the option. – Angio Sep 07 '21 at 02:23
  • Did you read the answer I linked? There's an enhanced version of `getopt` on Linux that handles short and long options. Are you concerned about portability to non-Linux UNIXes like MacOS? If not, if you're just targeting Linux, its `getopt` works really well. – John Kugelman Sep 07 '21 at 02:27
  • I am trying to write something for gnu, and are giving me hell against using `getopt`. But yes, I use linux getopt for some of my scripts. Works really well. – Angio Sep 07 '21 at 02:33
  • @JohnKugelman In that link you sent me, there are a few good examples to handle spaces and equal signs. – Angio Sep 07 '21 at 02:38

0 Answers0