如何在Bash中使用getopt处理长选项?

4

我在Bash中有以下代码:

declare {BPM_USERNAME,BPM_PASSWORD,HOST,TARGET_IP,OVERRIDE_STATUS}=''
OPTS=`getopt -a --longoptions username:,password:,csc:,ip:,override: -n "$0" -- "$@"`
eval set -- "$OPTS"

if [ $? != 0 ] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi

while true; do
    echo ""
    echo $OPTS
    echo $1
    echo $2

  case "$1" in
    --username )
        BPM_USERNAME=$2
        shift 2
        ;;
    --password )
        BPM_PASSWORD=$2
        shift 2
        ;;
    --csc )
        HOST=$2
        shift 2
        ;;
    --ip )
        TARGET_IP=$2
        shift 2
        ;;
    --override )
        OVERRIDE_STATUS=$2
        shift 2
        ;;
    --)
        shift
        echo "Breaking While loop"
        break
        ;;
    *)
        echo ""
        echo "Error in given Parameters. Undefined: "
        echo $*
        echo ""
        echo "Usage: $0 [--username BPM_USERNAME] [--password BPM_PASSWORD] [--ip IP ADDRESS_OF_VyOS/BPM] [--csc CLIENT_SHORT_CODE] [--override TRUE/FALSE]"
        exit 1
  esac
done

我向Bash输入以下命令(脚本名称为UpdateSSL.sh):

./UpdateSSL.sh -username bpmadmin -password bpmadmin -ip 10.91.201.99 -csc xyz -override False

但我并没有解析选项,而是得到了以下结果(表明 while 循环执行了 *) 分支):

'bpmadmin' --password 'bpmadmin' --ip '10.91.201.99' --csc 'xyz' --override 'False' --
bpmadmin
--password

Error in given Parameters. Undefined: 
bpmadmin --password bpmadmin --ip 10.91.201.99 --csc xyz --override False --

Usage: ./UpdateSSL.sh [--username BPM_USERNAME] [--password BPM_PASSWORD] [--ip IP ADDRESS_OF_VyOS/BPM] [--csc CLIENT_SHORT_CODE] [--override TRUE/FALSE]

我不知道自己做错了什么。


eval 是不必要的;set -- $OPTS(无引号)就足够了。 - chepner
1
做了那个。但是 while 循环仍然进入 *) 情况。 - Ahmad Shah
1个回答

6
答案实际上在 man 页面 的最后:

如果您不想使用任何短选项变量,则语法并不直观(您必须显式将它们设置为空字符串)。

为了使 getopt 运行时没有短选项,您必须手动指定 -o '' 作为第一个参数。我做了一些其他更改,并且以下内容在我的系统上运行良好(请参见 *** 标记):
#!/bin/bash

# *** Make sure you have a new enough getopt to handle long options (see the man page)
getopt -T &>/dev/null
if [[ $? -ne 4 ]]; then echo "Getopt is too old!" >&2 ; exit 1 ; fi

declare {BPM_USERNAME,BPM_PASSWORD,HOST,TARGET_IP,OVERRIDE_STATUS}=''
OPTS=$(getopt -o '' -a --longoptions 'username:,password:,csc:,ip:,override:' -n "$0" -- "$@")
    # *** Added -o '' ; surrounted the longoptions by ''
if [[ $? -ne 0 ]] ; then echo "Failed parsing options." >&2 ; exit 1 ; fi
    # *** This has to be right after the OPTS= assignment or $? will be overwritten

set -- $OPTS
    # *** As suggested by chepner

while true; do
    # ... no changes in the while loop
done

@AhmadShah 你有机会试一试吗? - cxw
2
尝试将 set -- $OPTS 更改为 eval set -- "$OPTS" ... 这段代码示例替代方案更好地处理包含空格的参数"$@"。 - NevilleDNZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接