【问题标题】:Odd Getopt (1) parsing behavior奇数Getopt(一)解析行为
【发布时间】:2017-06-24 19:12:39
【问题描述】:

使用 getopt (1) 解析 bash 中的一些选项,当我从 cmd 行传递选项时,它不会评估。它默认为 --) “双破折号” case 语句并在我提供其他选项时传递它们,不知道为什么它会导致这种奇怪的行为,代码如下:

parse_args() {
    cmd=""              # Default none
    isparsed=0          # If args parsed = 1

    # Check the number of arguments. If none are passed, print help and exit
    options=$(getopt -o hs:d:c:p:i: -l help,source:,destination:,connection:,platform:,install: -n "cdr" -- "$@")

    # If the number of arguments after processing them using getopt is larger 
    # than zero, then it means there is an unknown argument.
    if [[ $? -ne 0 ]]; then
        HELP
        exit 1
    fi

    printdbg "parsing options"
    eval set -- "$options"
    while true; do
        case "$1" in
            -h) # Show help option menu
                HELP
                exit 1
                ;;
            -s|--source) # Parse options to source sub command
                cmd=$2 # Remove 'source' from the argument list
                shift;
                if [[ $cmd == "sqlite" ]]; then
                    SOURCE="sqlite"
                elif [[ $cmd == "mysql" ]]; then
                    SOURCE="mysql"
                else
                    HELP
                    exit 1
                fi
                isparsed=1
                ;;
            -d|--destination) # Parse options to destination sub command
                cmd=$2 # Remove 'destination' from the argument list
                shift;
                if [[ $cmd == "postgre" ]]; then
                    DESTINATION="postgre"
                elif [[ $cmd == "riak" ]]; then
                    DESTINATION="riak"
                elif [[ $cmd == "both" ]]; then
                    DESTINATION="both"
                else
                    HELP
                    exit 1
                fi
                isparsed=1
                ;;
            -c|--connection) # Parse options to connection sub command
                cmd=$2 # Remove 'connection' from the argument list
                shift; printdbg "$cmd"
                if [[ ! -z $cmd ]]; then
                    SOURCE_CONN=$(echo "$cmd" | awk -F "::" '{print $1}')
                    DESTINATION_CONN=$(echo "$cmd" | awk -F "::" '{print $2}')
                    parse_csv "$SOURCE_CONN"  #stored in PARSED_ARR
                    echo ${PARSED_ARR[@]}
#                    ${DESTINATION_CONN:=${PARSED_ARR}}
                else
                    HELP
                    exit 1
                fi
                isparsed=1
                ;;
            -p|--platform) # Parse options to platform sub command
                cmd=$2 # Remove 'platform' from the argument list
                shift;
                if [[ $cmd == "csv" ]]; then
                    CDR_TYPE=1
                elif [[ $cmd == "api" ]]; then
                    CDR_TYPE=2
                elif [[ $cmd == "freeswitch" ]]; then
                    CDR_TYPE=3
                elif [[ $cmd == "asterisk" ]]; then
                    CDR_TYPE=4
                elif [[ $cmd == "yate" ]]; then
                    CDR_TYPE=5
                elif [[ $cmd == "kamailio" ]]; then
                    CDR_TYPE=6
                elif [[ $cmd == "opensips" ]]; then
                    CDR_TYPE=7
                elif [[ $cmd == "sipwise" ]]; then
                    CDR_TYPE=8
                elif [[ $cmd == "veraz" ]]; then
                    CDR_TYPE=9
                else
                    HELP
                    exit 1
                fi
                isparsed=1
                ;;
            -i|--install) # Parse options to install sub command
                cmd=$2 # Remove 'install' from the argument list
                shift;
                if [[ $cmd == "sqlite" ]]; then
                    install_dependencies
                    install_sqlite
                elif [[ $cmd == "mysql" ]]; then
                    install_dependencies
                    install_mysql
                elif [[ $cmd == "postgre" ]]; then
                    install_dependencies
                    install_postgre
                elif [[ $cmd == "riak" ]]; then
                    printwarn "This feature will be supported in future versions"
                    exit 1
                elif [[ $cmd == "pusher" ]]; then
                    install_dependencies
                    install_golang
                    install_cdrpusher
                    install_supervisord
                elif [[ $cmd == "stats" ]]; then
                    install_dependencies
                    install_golang
                    install_cdrstats
                else
                    HELP
                    exit 1
                fi
                isparsed=1
                ;;
            --) 
                shift
                break
                ;;
        esac
    done
}

我可以说它在 case 语句中默认为该点,因为仍然没有设置 isparsed 标志 ( == 0 ),我从我的 main() 将错误打印到控制台

main() {
    . cdr_funcs
    check_permissions
    detect_os
    parse_args

    if [[ ${isparsed} == 1 ]]; then
        INSTALL_COMPLETE_MESG
        exit 0
    fi

    printerr "isparsed flag == 0"
    HELP
    exit 1
}

使用 -h 标志运行会明显地表明这一点:

devbox cdr # ./cdr -h
[DEBUG] [check_permissions]: Root Permissions Validated
[DEBUG] [detect_os]: Starting OS Platform detection
[DEBUG] [detect_os]: Checking OS Compatibility
[DEBUG] [detect_os]: OS detected: [linux] (OS is supported)
[DEBUG] [detect_os]: Finished OS detection
[DEBUG] [parse_args]: parsing options
[ERROR] [main]: isparsed flag == 0

【问题讨论】:

    标签: bash shell parsing getopt


    【解决方案1】:

    在函数 (parse_args) 内部,"$@" 扩展为来自函数调用的参数,而不是封闭脚本。没有任何参数,因此getopt 看不到任何参数,也不会产生任何选项。

    如果你想用函数分析脚本参数,你需要将它们提供给函数:

    parse_args "$@"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-05
      • 2010-11-06
      • 2018-07-26
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 2013-10-29
      相关资源
      最近更新 更多