如何使用 getopts 接受不接受任何内容、一个标志、一个带有参数的标志和一个带有两个参数的标志

如何使用 getopts 接受不接受任何内容、一个标志、一个带有参数的标志和一个带有两个参数的标志

我目前已按以下方式设置 getopts:

while getopts ":p:s:d:g:i:h:" opt; do
        case ${opt} in
            p )
                if [[ $logging = true ]]
                then
                    echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose plex from the command line with the argument $OPTARG" >> $logfolder/advancedplexapi.log
                fi
                selection="plex"
                argument=true
                optarg="$OPTARG"
                ;;

            s )
                if [[ $logging = true ]]
                then
                    echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose sonarr from the command line with the argument $OPTARG" >> $logfolder/advancedplexapi.log
                fi
                selection="sonarr"
                argument=true
                optarg="$OPTARG"
                ;;

            d )
                if [[ $logging = true ]]
                then
                    echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose deluge from the command line with the argument $OPTARG" >> $logfolder/advancedplexapi.log
                fi
                selection="deluge"
                argument=true
                optarg="$OPTARG"
                ;;

            g )
                if [[ $logging = true ]]
                then
                    echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose ip geolocation from the command line with the argument $OPTARG" >> $logfolder/advancedplexapi.log
                fi
                selection="ip geolocation"
                argument=true
                optarg="$OPTARG"
                ;;

            i )
                if [[ $logging = true ]]
                then
                    echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose the info page from the command line but supplied an argument" >> $logfolder/advancedplexapi.log
                fi
                selection="info"
                argument=true
                optarg="$OPTARG"
                ;;

            h )
                if [[ $logging = true ]]
                then
                    echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose help page for flags from the command line but supplied an argument" >> $logfolder/advancedplexapi.log
                fi
                echo "The help flag doesn't support an argument"
                usage | column -t -s "|"
                exit
                ;;

            : )
                case "$OPTARG" in
                    p )
                        if [[ $logging = true ]]
                        then
                            echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose plex from the command line" >> $logfolder/advancedplexapi.log
                        fi
                        selection="plex"
                        ;;

                    s )
                        if [[ $logging = true ]]
                        then
                            echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose sonarr from the command line" >> $logfolder/advancedplexapi.log
                        fi
                        selection="sonarr"
                        ;;

                    d )
                        if [[ $logging = true ]]
                        then
                            echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose deluge from the command line" >> $logfolder/advancedplexapi.log
                        fi
                        selection="deluge"
                        ;;

                    g )
                        if [[ $logging = true ]]
                        then
                            echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose ip geolocation from the command line" >> $logfolder/advancedplexapi.log
                        fi
                        selection="ip geolocation"
                        ;;

                    i )
                        if [[ $logging = true ]]
                        then
                            echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose the info page from the command line" >> $logfolder/advancedplexapi.log
                        fi
                        selection="info"
                        ;;

                    h )
                        if [[ $logging = true ]]
                        then
                            echo "$(date '+%d/%m/%Y %H:%M:%S') |     info      | user chose help page for flags from the command line" >> $logfolder/advancedplexapi.log
                        fi
                        usage | column -t -s "|"
                        exit
                        ;;
                esac
                ;;

            \? )
                echo "Invalid usage"
                usage | column -t -s "|"
                exit
                ;;
        esac
    done 2>/dev/null
    shift $((OPTIND -1))

此代码接受以下内容:

./script.sh                #-> just run the script without any variables set
./script.sh -p             #-> selection=plex
./script.sh -s series      #-> selection=sonarr & argument=true & optarg=series
./script.sh -h info        #-> error because -h flag doens't support arguments

#script can be run barebones (./script.sh)
#script can be run with a flag (only one allowed: -p|-s|-d|-g|-i|-h) (./script.sh -p)
#script can be run with a flag and an argument (argument only allowed when using: -p|-s|-d|-g|-i)(./script.sh -s series) (./script.sh -h info -> not allowed)

我的问题:

我需要调整代码以接受第二个参数,但我真的不知道如何做:

My goal is:
./script.sh -p history list
=
selection=plex
argument=true
optarg=history
second_argument=true
second_optarg=list

./script.sh -p sessions
=
selection=plex
argument=true
optarg=sessions
second_argument=false
second_optarg=
  • -p -s 和 -d 允许第二个参数。
  • 如果其他标志与两个参数一起使用(仅允许零个或一个参数的标志),则运行echo "The help flag doesn't support an second argument" && usage | column -t -s "|"
  • 当没有给出第二个参数时,second_optarg 需要为空字节
  • 当没有给出第二个参数时,second_argument 需要设置为 false
  • 第二个参数(当然仅适用于 -p -s 和 -d)不是必需的,它是可选的

答案1

看起来用户只允许输入一个选项:-p 或 -s 或...但不能输入任何组合。我建议解析选项没有参数:

selections=()
while getopts ":psdgih" opt; do
    case ${opt} in
        p)  selections+=("plex") ;; 
        s)  selections+=("sonarr") ;; 
        d)  selections+=("deluge") ;; 
        g)  selections+=("ip geolocation") ;; 
        i)  selections+=("info") ;; 
        h)  show_help; exit ;;
        \?) echo "Invalid usage"
            usage | column -t -s "|"
            exit
            ;;
    esac
done 2>/dev/null

case ${#selections[@]} in
    0)  selection="default case" ;;
    1)  selection=${selections[0]} ;;
    *)  echo "only one selection allowed" >&2; exit 1 ;;
esac
shift $((OPTIND - 1))

现在你可以"$@"随意使用:

case $# in
    0)  echo "some error" >&2; exit 1 ;;
    1)  optarg=$1
        second_argument=false
        ;;
    *)  optarg=$1
        second_argument=true
        second_optarg=$2
        ;;
esac

或者

case $1 in
    history)
        case $2 in
            list) : ...
                  ;;

相关内容