Shell脚本未正确读取可选参数

Shell脚本未正确读取可选参数,shell,sh,Shell,Sh,我有这个脚本文件: #!/bin/sh Show_Error() { echo -e "\033[31m ERROR \033[0m $1" } if [ "$1" = "-help" ] then echo "<input> - input file name or input URL" else for i in "$@" do case $i in -l=*|--ddloc=*) DDLOC="${i#*=}" shift

我有这个脚本文件:

#!/bin/sh

Show_Error() {
        echo -e "\033[31m ERROR \033[0m $1"
}

if [ "$1" = "-help" ]
then
    echo "<input> - input file name or input URL"
else


for i in "$@"
do
case $i in
    -l=*|--ddloc=*)
    DDLOC="${i#*=}"
    shift # past argument=value
    ;;
    -l|--ddloc)
    shift # past argument
    DDLOC="$1"
    shift # past value
    ;;
    *)
          # unknown option
    ;;
esac
done

if [ -z "$DDLOC" ]
then
       Show_Error 'File is missing. Use -l or --ddloc.'
else
echo "Location::: $DDLOC"
fi
fi
#/垃圾箱/垃圾箱
显示错误(){
echo-e“\033[31m错误\033[0m$1”
}
如果[“$1”=”-help”]
然后
echo“-输入文件名或输入URL”
其他的
对于“$@”中的i
做
案例一
-l=*|--ddloc=*)
DDLOC=“${i#*=}”
移位#过去参数=值
;;
-l |--ddloc)
shift#过去的论点
DDLOC=“$1”
移位#过去值
;;
*)
#未知选项
;;
以撒
完成
如果[-z“$DDLOC”]
然后
Show_Error“文件丢失。请使用-l或--ddloc。”
其他的
echo“位置::$DDLOC”
fi
fi
如果我运行命令:
/tdl2ddlgen.sh-s ssss-m lll-l LOC


>给出:<代码> >位置::SSSS< <代码> >位置:::LOC < /P> > P> >在“$@”/CODE >中,我认为<代码>将所有值从<代码> $@ /代码>中复制,然后将代码> $i < /代码>依次设置。您可以通过检测代码来观察正在发生的事情:

for i in "$@"
do
echo "\$i = $i; \$@ = ($@)"
case $i in
    # ...
给出输出:

$i = -s; $@ = (-s sssss -m 111 -l LOC)
$i = sssss; $@ = (-s sssss -m 111 -l LOC)
$i = -m; $@ = (-s sssss -m 111 -l LOC)
$i = 111; $@ = (-s sssss -m 111 -l LOC)
$i = -l; $@ = (-s sssss -m 111 -l LOC)
$i = LOC; $@ = (-m 111 -l LOC)
Location::: sssss
实际上出了问题的是,当你得到一个未知的值时,你没有转移掉
$1
选项。如果添加班次:

for i in "$@"
do
echo "\$i = $i; \$@ = ($@)"
case $i in
    -l=*|--ddloc=*)
    DDLOC="${i#*=}"
    shift # past argument=value
    ;;
    -l|--ddloc)
    shift # past argument
    DDLOC="$1"
    shift # past value
    ;;
    *)
          # unknown option
    shift
    ;;
esac
done
然后您将得到您期望的结果:

$i = -s; $@ = (-s sssss -m 111 -l LOC)
$i = sssss; $@ = (sssss -m 111 -l LOC)
$i = -m; $@ = (-m 111 -l LOC)
$i = 111; $@ = (111 -l LOC)
$i = -l; $@ = (-l LOC)
$i = LOC; $@ = ()
Location::: LOC
尽管行为仍然不完全正确-
LOC
参数被处理两次。为了防止双重处理,而不是为循环复制
$@
,您可以执行以下操作:

while [ -n "$1" ]
do
case $1 in
    # ...

shift
for
循环中没有任何有用的操作。您已经有一个参数列表,
“$@”
,并且,
$i
正在逐个遍历此列表。
shift
对已在
for
语句中展开的参数列表没有任何作用。
Show_Error
听起来像是打印错误消息的函数。错误消息属于stderr:
echo“…”&2