使用getopts的多个选项参数(bash)

时间:2013-04-24 07:50:04

标签: linux bash shell unix getopts

我正在尝试使用bash中的getopts处理命令行参数。其中一个要求是处理任意数量的选项参数(不使用引号)。

第一个例子(仅获取第一个参数)

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

3 个答案:

答案 0 :(得分:13)

我认为你想要的是从一个选项中获取值列表。为此,您可以根据需要多次重复该选项,并将其参数添加到数组中。

#!/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

答案 1 :(得分:3)

您可以自己解析命令行参数,但不能将getopts命令配置为识别单个选项的多个参数。 fedorqui's recommendation是一个不错的选择。

以下是一种自行解析选项的方法:

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

答案 2 :(得分:2)

这是我使用用户定义函数执行此操作的方式: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 处使用。