我正在尝试制作一个可以同时执行不同数量程序的脚本(prog1,prog2,... prog5,甚至更多)。
它只能是prog1,或者是prog1& prog2,或者是prog1& prog2& prog3,prog1& prog3& prog4& prog6& prog8
每个程序都可以使用不同的选项进行调用,并根据它的调用选项执行不同的操作。
例如,可以用以下不同的方式调用prog1:
prog1 -d "-f 10 -g 20"
( - d是该特定选项的选项和“-f 10 -g 20”参数)prog1 -B
prog1 -R "-l 2 -m 9"
prog1 -S "10 20 30"
它也可以通过以下组合调用:
prog1 -d "-f 10 -g 20" -B -R "-l 2 -m 9"
我决定使用两阶段getopt(嵌套getopt)来解决这个问题。
在第一阶段,getopt将处理用户提供的不同程序作为脚本的输入。在第二阶段,getopt将处理每个程序可以获得的不同选项和参数。
我的脚本如下:
#!/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“
理想情况下,脚本应该使用以下调用运行:
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
等
您对如何克服这个问题有任何想法吗?
提前谢谢
答案 0 :(得分:0)
您的问题部分在于您将shell的当前参数列表设置了两次:
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
第二组选项打破了第一组选择。
“陷入循环”问题的原因不太明显。
要解决这个问题很难解决。我认为你必须有一个循环来处理程序级选项;那么,对于每个要执行的程序,你需要在第一个选项处理循环之后(不嵌套)的新循环:
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.
这是运行两个程序的工作代码。命令选项是无情的并行,但它们也是不同的。其中一个关键变化是从相应的已保存选项字符串中设置“每个程序”选项。它被削减以处理两个程序。我的GNU getopt
版本未安装在系统getopt
之前,因此该变量用于定义要运行的getopt
程序。
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
$