我有一个名为manp的bash脚本,它有一些案例选项,如下所示:
ARGS=$@
while [[ $# -gt 0 ]] ; do
case "$1" in
--log)
LOG=1
shift
;;
--upgrade*)
UPGRADE=1
echo "$ARGS" # Outputs --upgrade tclclean==2.1 pms ubu==2.2
PCKG_INFO=${ARGS#*\ } # Supposed to strip everything before the space in front of tclclean
shift
;;
-*|*)
echo "Unknown command '$ARGS'"
exit 1
;;
esac
done
if [ ! -z "$UPGRADE" ]; then
echo "$PCKG_INFO"
exit 0
fi
我要做的是运行$ manp --upgrade tclclean==2.1 pms ubu==2.2
并将--upgrade
案例开始,同时将tclclean==2.1 pms ubu==2.2
放入PCKG_INFO变量
当我运行该命令时,我得到--upgrade
和*|*
两种情况,这是输出:
--upgrade tclclean==2.1 pms ubu==2.2 # Output of echo ARGS
Unknown command '--upgrade tclclean==2.1 pms ubu==2.2' # Output of echo PCKG_INFO
所以问题是它运行两种情况并且PCKG_INFO=${ARGS#*\ }
不剥离任何东西......
感谢
答案 0 :(得分:0)
首先,我不知道你为什么不只是使用getopts?
ARGS=" tclclean==2.1 pms ubu==2.2"
PCKG_INFO=${ARGS#*^ $} # Supposed to strip everything before the space in front of tclclean
应该是
PCKG_INFO=${ARGS#* }
然而,套住$ @和转移似乎是错误的。你应该切换到getopts
答案 1 :(得分:0)
我找到了一种方法,可以通过突破--upgrade
案例来防止进入这两种情况,因为它离开整个循环而不会迭代命令中的其他参数。
--upgrade*)
UPGRADE=1
echo "$ARGS"
PCKG_INFO=${ARGS#*\ }
break
;;
答案 2 :(得分:0)
问题是你的转变只是删除一个案例的参数。您放入PCKG_INFO的后续参数仍在命令行中。循环的下一次迭代将以参数" tclclean == 2.21"开始。因此,对于您放入PCKG_INFO的每个参数,您还需要转换。此外,PCKG_INFO=${ARGS#*\ }
并没有按照您的想法行事。它没有更改 ARGS的内容。它只是返回 ARGS的子串。 ARGS保持不变( shift 正在进行除外)。
现在,如果你确切知道在你想要的升级之后有多少参数,那么你可以做多次转换(甚至是shift 3
)。如果你可以保证带有参数的--upgrade将是行中的最后一件事,那么你可以先调整switch参数,然后使PCKG_INFO = $ ARGS。但是如果你不能确保这些事情中的任何一个,你就需要找到一种方法来确定你何时完成PCKG_INFO args,并且这将需要一个内在的循环,在那里迭代后续参数(再次,shift
每个参数),直到到达终止标记,然后继续使用外部case
循环。