Calling different programs with different parameters and different arguments for each option

I am trying to make a script that can execute a different number of programs at the same time (prog1, prog2, ... prog5 or even more).

It can only be prog1 or prog1 and prog2 or prog1 and prog2 and prog3, prog1 and prog3 and prog4 and prog6 and prog8

Each program can be called with different parameters and will do different things depending on its calling options.

For example, prog1 can be called differently:

  • prog1 -d "-f 10 -g 20" (-d is the option and arguments "-f 10 -g 20" for this particular option)
  • prog1 -B
  • prog1 -R "-l 2 -m 9"
  • prog1 -S "10 20 30"

It can also be called up using its own combinations, such as: prog1 -d "-f 10 -g 20" -B -R "-l 2 -m 9"

I decided to use a two-step getopt (nested getopt) to deal with this problem.

In the first step, getopt will process the various programs that the user provides as input to the script. In the second step, getopt will process the various parameters and arguments that each program can receive.

My script is as follows:

 #!/bin/bash args=`getopt -o :v -l prog1:,prog2,prog3,prog4,prog5 -- " $@ "` # Here prog2,prog3..prog5 do not have a colon (:) to save some space but all of them will eventually get since when they are called they should have input arguments eval set -- "$args" 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" 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 shift 2;; --prog2 ) echo "similar things as in prog1"; shift ;; --prog3 ) echo "similar things as in prog1"; shift ;; --prog4 ) echo "similar things as in prog1"; shift ;; --prog5 ) echo "similar things as in prog1"; shift ;; -- ) shift; break;; esac done 

when I run the script like: my_script --prog1 -d "-f 10 -g 100" , it can get the -d argument, but somehow it gets into an infinite loop and at the same time cannot get another argument "- f 10 - g 100 "

Ideally, the script should run with calls such as:

  • my_script --prog1 -d "-f 10 -g 100" -R "-l 2 -m 9" --prog3 -M "-r 9 0.5 6" -F "-o 2 -q- 4" --prog5 .... etc

  • my_script --prog1 -d "-f 10 -g 100" .

  • my_script --prog1 -d "-f 10 -g 100" -B --prog3 -F "-o 2 -q- 4"

  • my_script --prog3 -F "-o 2 -q- 4" -M --prog2 -G

  • etc.

Do you have any ideas on how to overcome this problem?

Thank you in advance

0
source share
1 answer

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 # Now execute prog1? fi # And similarly for $opts2 .. $opts5. 

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 -- $@ " # Now execute prog1? fi if [ -n "$opts2" ] then args=$($GETOPT -of:AT:G: -- $opts2) eval set -- "$args" while [ $# -gt 0 ] do case $1 in -f ) echo "prog2 -f:$2"; shift 2;; -A ) echo "prog2 -A"; shift 1;; -T ) echo "prog2 -T:$2"; shift 2;; -G ) echo "prog2 -G:$2"; shift 2;; -- ) shift; break;; * ) echo "$0: oops processing prog2 - $1 unexpected" >&2; exit 1;; esac done echo "prog2 opts -- $@ " # Now execute prog2? fi 

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 $ 
0
source

Source: https://habr.com/ru/post/943510/


All Articles