簡體   English   中英

使用 getopts (bash) 的多個選項 arguments

[英]Multiple option arguments using getopts (bash)

我正在嘗試在 bash 中使用 getopts 處理命令行 arguments。其中一個要求是處理任意數量的選項 arguments(不使用引號)。

第一個示例(僅獲取第一個參數)

madcap:~/projects$ ./getoptz.sh -s a b c
-s was triggered
Argument: a

第二個例子(我希望它表現得像這樣但不需要引用參數“

madcap:~/projects$ ./getoptz.sh -s "a b c"
-s was triggered
Argument: a b c

有沒有辦法做到這一點?

這是我現在的代碼:

#!/bin/bash
while getopts ":s:" opt; do
    case $opt in
    s) echo "-s was triggered" >&2
       args="$OPTARG"
       echo "Argument: $args"
       ;;
   \?) echo "Invalid option: -$OPTARG" >&2
       ;;
    :) echo "Option -$OPTARG requires an argument." >&2
       exit 1
       ;;
    esac
done

我認為您想要的是從單個選項中獲取值列表。 為此,您可以根據需要多次重復該選項,並將其參數添加到數組中。

#!/bin/bash

while getopts "m:" opt; do
    case $opt in
        m) multi+=("$OPTARG");;
        #...
    esac
done
shift $((OPTIND -1))

echo "The first value of the array 'multi' is '$multi'"
echo "The whole list of values is '${multi[@]}'"

echo "Or:"

for val in "${multi[@]}"; do
    echo " - $val"
done

輸出將是:

$ /tmp/t
The first value of the array 'multi' is ''
The whole list of values is ''
Or:

$ /tmp/t -m "one arg with spaces"
The first value of the array 'multi' is 'one arg with spaces'
The whole list of values is 'one arg with spaces'
Or:
 - one arg with spaces

$ /tmp/t -m one -m "second argument" -m three
The first value of the array 'multi' is 'one'
The whole list of values is 'one second argument three'
Or:
 - one
 - second argument
 - three

您可以自己解析命令行參數,但無法將getopts命令配置為識別單個選項的多個參數。 fedorqui 的推薦是一個不錯的選擇。

這是自己解析選項的一種方法:

while [[ "$*" ]]; do
    if [[ $1 = "-s" ]]; then
        # -s takes three arguments
        args="$2 $3 $4"
        echo "-s got $args"
        shift 4
    fi
done

這是我使用用戶定義函數執行此操作的方法: getopts-extra

function getopts-extra () {
    declare i=1
    # if the next argument is not an option, then append it to array OPTARG
    while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do
        OPTARG[i]=${!OPTIND}
        let i++ OPTIND++
    done
}

# Use it within the context of `getopts`:
while getopts s: opt; do
    case $opt in
       s) getopts-extra "$@"
          args=( "${OPTARG[@]}" )
    esac
done

getoptz.sh 的完整示例:

#!/usr/bin/env bash

function getopts-extra () {
    declare i=1
    # if the next argument is not an option, then append it to array OPTARG
    while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do
        OPTARG[i]=${!OPTIND}
        let i++ OPTIND++
    done
}

function main () {
    declare args
    declare OPTIND OPTARG opt
    while getopts :s: opt; do
        case $opt in
        s) getopts-extra "$@"
           args=( "${OPTARG[@]}" )
           ;;
       \?) echo "Invalid option: -$OPTARG" >&2
           ;;
        :) echo "Option -$OPTARG requires an argument." >&2
           exit 1
           ;;
        esac
   done

   declare i
   for i in "${!args[@]}"; do
       echo "args[$i]: ${args[i]}"
   done
}

main "$@"

exit

測試:

bash getoptz.sh -s a b c

輸出:

args[0]: a
args[1]: b
args[2]: c

此函數是名為xsh-lib/core的 bash 庫的一部分,可通過語法xsh /util/getopts/extra

我發現這更好,而不是使用getops 創建文件 tmp.sh 並復制以下代碼。

usage() {
    echo "Usage: 
    ./tmp.sh --cloud_provider gcp --source_path abc --destination_path def --refresh_frequency 100 --authenticate true --credential_path a.json
    "
}


while [ "$#" -gt 0 ]; do
    case $1 in
    -a | --authenticate)
        shift
        [[ $1 == -* ]] && continue
        export authenticate=$1
        ;;
    -cp | --credential_path)
        shift
        [[ $1 == -* ]] && continue
        export credential_path=$1
        ;;
    -c | --cloud_provider)
        shift
        [[ $1 == -* ]] && continue
        export cloud_provider=$1
        ;;
    -s | --source_path)
        shift
        [[ $1 == -* ]] && continue
        export source_path=$1
        ;;
    -d | --destination_path)
        shift
        [[ $1 == -* ]] && continue
        export destination_path=$1
        ;;
    -r | --refresh_frequency)
        shift
        [[ $1 == -* ]] && continue
        export refresh_frequency=$1
        ;;
    --)
        shift
        break
        ;;
    esac
    shift
done

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM