我得到了两次与我的脚本一起使用的参数:
第一次使用以下代码,以确保没有我不想要的参数(我只考虑arg1:arg2:arg3)
PARAM=$@
while [ "$#" -gt "0" ]; do
case $1 in
arg1)
shift2
;;
arg2)
shift
;;
arg3)
shift
;;
*)
echo "Usage : ./test.sh arg1 <VAL1> <VAL2> [arg2] [arg3]"
exit 2
;;
esac
shift
done
我想再次解析这些参数,并且当我得到arg1时能够得到以下两个参数,所以我开始使用这样的东西:
for command in $PARAM
do
case $command in
arg1)
shift
VALUE1=$command
shift
VALUE2=$command
exec_arg1
;;
esac
shift
但是在使用“shift”时,我得到错误 shift:无法移动那么多
shebang是“#!/ bin / sh”,我正在寻找解决方案,而不必使用bash的shebang(即“#!/ bin / bash”)
答案 0 :(得分:2)
您无法将列表连接到字符串并安全地将其重新转换为列表(没有complex helper function)。请参阅this FAQ。
shift
在不同的shell中表现不同。在Bash和Zsh中,当没有位置参数时,shift
只返回false。包括Dash在内的许多shell(与POSIX相反,可能是因为ksh行为)会引发致命错误。 ksh93通过command
内置提供了一种解决方法,但这似乎也没有被POSIX指定,尽管这个workaroud无论如何也适用于Dash,但不是mksh
(mksh中也有一个bug)我昨天刚刚发现,这可以阻止它工作,维护者可能不会以允许解决方法的方式修复它。 Busybox也不遵循POSIX,也没有提供有意义的退出代码。
无论如何,关键是你不能依赖shift
,因为这里有很多炮弹都有虫子。如果可能的话,你应该迭代参数而不移动它们,并以一种确保你不像现在这样移动边缘的方式测试剩余参数的数量。我不认为你预先验证参数的想法比仅仅同时验证和解析更好。
#!/bin/sh
f()
if ! ${_called_f+false}; then
while ! ${1+false}; do
case $1 in
arg1)
${3+:} return 1
value1=$2 value2=$3
shift 3
exec_arg1
;;
arg[23])
${2+:} return 1
value1=$1
shift
"exec_arg${value1##"${value1%?}"}" # Only do this crap if restricted to POSIX
;;
*)
return 1
esac
done
else
# Hack nobody will understand since this probably isn't what you want anyway.
_called_f= value1= value2= command eval \
'typeset +x value{1,2} 2>/dev/null; f "$@"'
fi
if ! f "$@"; then
echo 'Error parsing args, exiting...' >&2
exit 1
fi
另请参阅:option parsing