9

我正在尝试创建一个脚本,该脚本将带有一个带有可选选项的标志。使用 getopts 可以在标志之后指定一个强制参数(使用冒号),但我想保持它是可选的。

它会是这样的:

./install.sh -a 3

或者

./install.sh -a3

其中“a”是标志,“3”是 a 后面的可选参数。

提前致谢。

4

5 回答 5

9

外部程序通过getopt在选项名称中添加双冒号来允许选项具有单个可选参数。

# Based on a longer example in getopt-parse.bash, included with
# getopt
TEMP=$(getopt -o a:: -- "$@")
eval set -- "$TEMP"
while true ; do
   case "$1" in
     -a)
        case "$2" in 
          "") echo "Option a, no argument"; shift 2 ;;
          *) echo "Option a, argument $2"; shift 2;;
        esac ;;
     --) shift; break ;;
     *) echo "Internal error!"; exit 1 ;;
   esac
done
于 2013-03-20T13:34:18.613 回答
2

以下是没有的getopt,它需要一个带有 -a 标志的可选参数:

for WORD; do
        case $WORD in
            -a?)  echo "single arg Option"
                SEP=${WORD:2:1}
                echo $SEP
                shift ;;
            -a) echo "split arg Option"
                if [[ ${2:0:1} != "-" && ${2:0:1} != ""]] ; then
                 SEP=$2
                 shift 2
                 echo "arg present"
                 echo $SEP
                else
                 echo "optional arg omitted"
                fi ;;
            -a*) echo "arg Option"
                SEP=${WORD:2}
                echo $SEP
                shift ;;
            -*) echo "Unrecognized Short Option"
                echo "Unrecognized argument"
            ;;
        esac
done

其他选项/标志也可以轻松添加。

于 2013-03-20T13:58:13.100 回答
-1

使用 getopt 功能。在大多数系统上,man getopt将为它生成文档,甚至在脚本中使用它的示例。从我系统上的手册页:

以下代码片段显示了如何处理可以采用选项 -a 和 -b 以及需要参数的选项 -o 的命令的参数。

       args=`getopt abo: $*`
       # you should not use `getopt abo: "$@"` since that would parse
       # the arguments differently from what the set command below does.
       if [ $? != 0 ]
       then
               echo 'Usage: ...'
               exit 2
       fi
       set -- $args
       # You cannot use the set command with a backquoted getopt directly,
       # since the exit code from getopt would be shadowed by those of set,
       # which is zero by definition.
       for i
       do
               case "$i"
               in
                       -a|-b)
                               echo flag $i set; sflags="${i#-}$sflags";
                               shift;;
                       -o)
                               echo oarg is "'"$2"'"; oarg="$2"; shift;
                               shift;;
                       --)
                               shift; break;;
               esac
       done
       echo single-char flags: "'"$sflags"'"
       echo oarg is "'"$oarg"'"

此代码将接受以下任何等效项:

       cmd -aoarg file file
       cmd -a -o arg file file
       cmd -oarg -a file file
       cmd -a -oarg -- file file
于 2013-03-20T13:29:56.480 回答
-1

在 bash 中有一些隐式变量:

    $#: contains number of arguments for a called script/function

    $0: contains names of script/function
    $1: contains first argument
    $2: contains second argument
    ...
    $n: contains n-th argument

例如:

    #!/bin/ksh

    if [ $# -ne 2 ]
    then
        echo "Wrong number of argument - expected 2 : $#"
    else
        echo "Argument list:"
        echo "\t$0"
        echo "\t$1"
        echo "\t$2"
    fi
于 2013-03-20T13:32:09.843 回答
-1

我的解决方案:

#!/bin/bash
count=0
skip=0
flag="no flag"
list=($@) #put args in array
for arg in $@ ; do #iterate over array
    count=$(($count+1)) #update counter
    if [ $skip -eq 1 ]; then #check if we have to skip this args
        skip=0
        continue
    fi
    opt=${arg:0:2} #get only first 2 chars as option
    if [ $opt == "-a" ]; then #check if option equals "-a"
       if [ $opt == $arg ] ; then #check if this is only the option or has a flag
            if [ ${list[$count]:0:1} != "-" ]; then #check if next arg is an option
                skip=1 #skip next arg
                flag=${list[$count]} #use next arg as flag
            fi
       else
            flag=${arg:2} #use chars after "-a" as flag
       fi 
    fi
done

echo $flag
于 2013-03-20T13:50:02.967 回答