使用不同的选项和每个选项的不同参数调用不同的程序 [英] Calling different programs with different options and different arguments for each option

查看:138
本文介绍了使用不同的选项和每个选项的不同参数调用不同的程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个可以同时执行不同数量程序(prog1,prog2,... prog5甚至更多)的脚本.

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

它只能是prog1或prog1& prog2或prog1& prog2& prog3,prog1& prog3& prog4& prog6& prog8

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

每个程序可以使用不同的选项来调用,并且根据其调用选项将执行不同的事情.

Each program can be called with different options and will execute different things depending on it's calling options.

例如,可以通过以下几种不同的方式调用prog1:

For instance prog1 can be called in these different ways:

  1. prog1 -d "-f 10 -g 20"(-d是一个选项,该特定选项的参数是"-f 10 -g 20")
  2. prog1 -B
  3. prog1 -R "-l 2 -m 9"
  4. prog1 -S "10 20 30"
  1. prog1 -d "-f 10 -g 20" (-d is an option and "-f 10 -g 20" arguments for that specific option)
  2. prog1 -B
  3. prog1 -R "-l 2 -m 9"
  4. prog1 -S "10 20 30"

它也可以用其组合来调用,例如: prog1 -d "-f 10 -g 20" -B -R "-l 2 -m 9"

It can also be called with its combinations like: prog1 -d "-f 10 -g 20" -B -R "-l 2 -m 9"

我决定使用两阶段的getopt(嵌套的getopt)来解决此问题.

I decided to use a two stage getopt (nested getopt) to cope with this problem.

在第一阶段,getopt将处理用户作为脚本输入提供的不同程序.在第二阶段,getopt将处理每个程序可以获取的不同选项和参数.

In the first stage getopt will handle the different programs that the user gives as input to the script. In the second stage the getopt will handle the different options and arguments that each program can get.

我的脚本如下:

#!/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

当我以以下方式运行脚本时:my_script --prog1 -d "-f 10 -g 100"它可以获取-d参数,但以某种方式使其陷入无限循环,并且同时无法获取另一个参数"-f 10 -g 100 "

when I run the script as:my_script --prog1 -d "-f 10 -g 100" it is able to get the -d argument but somehow it gets in an infinite loop and at the same time is not able to get the other argument "-f 10 -g 100"

理想情况下,脚本应通过以下调用来运行:

Ideally the script should run with calls such as :

  1. 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

您对如何解决此问题有任何想法吗?

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

提前谢谢

推荐答案

您的问题部分在于您两次设置了shell的当前参数列表:

Your problem is in part that you set the shell's current argument list 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 options blows away the first set.

卡在循环中"问题的原因不太明显.

The cause of the 'stuck in a loop' problem is less obvious.

要解决此问题将非常困难.我认为您将必须有一个循环来处理程序级别的选项;然后,对于每个要执行的程序,在第一个选项处理循环之后(而不是嵌套在其中)将需要一个新循环:

It is going to be hard to fix this. I think you will have to have a loop to process the program level options; then, for each program that is to be executed, you will need a new loop after (not nested within) the first option processing loop:

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

这是运行两个程序的工作代码.命令选项无情地平行,但它们也有所不同.关键更改之一是从适当的已保存选项字符串中设置每个程序"选项.它被缩减为仅处理两个程序.我的GNU getopt版本未安装在系统getopt之前,因此是用于定义要运行哪个getopt程序的变量.


SSCCE

Here's working code for running two programs. The command options are ruthlessly parallel, but they're different too. One of the key changes is setting the 'per program' options from the appropriate saved option strings. It is cut down to handle just two programs. My version of GNU getopt is not installed ahead of the system getopt, hence the variable to define 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 -o d: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 -o f: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

示例运行

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

这篇关于使用不同的选项和每个选项的不同参数调用不同的程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆