Your problem, in part, is that you specify a list of shell arguments twice:
args=$(getopt -o :v -l prog1:,prog2,prog3,prog4,prog5 -- " $@ ") eval set -- "$args" # First set of arguments while true; do case $1 in -v ) echo "VERBOSE"; shift;; --prog1 ) echo "prog1 has been chosen with the following option:$2" args=`getopt -o :d:BR:S: -- " $@ "` eval set -- "$args" # Second set of arguments blows away the first
The second set of parameters resets the first set.
The cause of the stuck in loop problem is less obvious.
Itβs hard to fix it. I think you will have to have a loop to process program level parameters; then for each program that needs to be executed, you will need a new cycle after (not nested inside) the first cycle of processing options:
args=$(getopt -o :v -l prog1:,prog2,prog3,prog4,prog5 -- " $@ ") eval set -- "$args" while true do case $1 in -v ) echo "VERBOSE"; shift;; --prog1 ) echo "prog1 has been chosen with the following options: $2" opts1="$2" shift 2;; --prog2 ) echo "prog2 has been chosen with the following options: $2" opts2="$2" shift 2;; --prog3 ) echo "prog3 has been chosen with the following options: $2" opts3="$2" shift 2;; --prog4 ) echo "prog4 has been chosen with the following options: $2" opts4="$2" shift 2;; --prog5 ) echo "prog5 has been chosen with the following options: $2" opts5="$2" shift 2;; -- ) shift; break;; esac done if [ -n "$opts1" ] then args=`getopt -o :d:BR:S: -- "$opts1"` eval set -- "$args" while true do case $1 in -d ) echo "-d:$2"; shift 2;; -B ) echo "-B"; shift;; -R ) echo "-R:$2" ;shift 2 ;; -S ) echo "-S:$2"; shift 2;; -- ) shift; break;; esac done
Sscce
This is where the code to run two programs works. The command parameters are ruthlessly parallel, but they are also different. One of the key changes is setting options for each program from the corresponding saved option lines. It is shortened to handle only two programs. My version of GNU getopt not installed before the getopt system, so the variable determines which getopt program to run.
GETOPT=/usr/gnu/bin/getopt args=$($GETOPT -o :v -l prog1:,prog2: -- " $@ ") eval set -- "$args" while [ $# -gt 0 ] do case $1 in -v ) echo "VERBOSE"; shift;; --prog1 ) echo "prog1 has been chosen with the following options: $2" opts1="$2" shift 2;; --prog2 ) echo "prog2 has been chosen with the following options: $2" opts2="$2" shift 2;; -- ) shift; break;; * ) echo "$0: oops! $1 unexpected" >&2; exit 1;; esac done echo "$0: residual arguments: $@ " if [ -n "$opts1" ] then args=$($GETOPT -od:BR:S: -- $opts1) eval set -- "$args" while [ $# -gt 0 ] do case $1 in -d ) echo "prog1 -d:$2"; shift 2;; -B ) echo "prog1 -B"; shift 1;; -R ) echo "prog1 -R:$2"; shift 2;; -S ) echo "prog1 -S:$2"; shift 2;; -- ) shift; break;; * ) echo "$0: oops processing prog1 - $1 unexpected" >&2; exit 1;; esac done echo "prog1 opts -- $@ "
Execution example
$ sh multiopts.sh -v --prog2 "-f file -A -G garbage -T tag -- zero one" \ > --prog1="-S silence -R rubbish -B -d dog -- aleph null" -- abc def VERBOSE prog2 has been chosen with the following options: -f file -A -G garbage -T tag -- zero one prog1 has been chosen with the following options: -S silence -R rubbish -B -d dog -- aleph null multiopts.sh: residual arguments: abc def prog1 -S:silence prog1 -R:rubbish prog1 -B prog1 -d:dog prog1 opts -- aleph null prog2 -f:file prog2 -A prog2 -G:garbage prog2 -T:tag prog2 opts -- zero one $