2

我正在寻找一种方法来提供以空格分隔的 IP 地址列表作为 bash 脚本的命名可选参数。我想获得下一个功能:

./bootstrap.sh -bx -c 192.168.1.1 192.168.1.2

这里bx是一些可选参数,-c应该获取 IP 地址列表作为参数。我getops用来处理参数,现在我将此参数提供为逗号分隔的字符串:

./bootstrap.sh -bx -c192.168.1.1,192.168.1.2

它运行良好,但对于用户来说看起来很丑陋且不直观。任何帮助表示赞赏。

4

2 回答 2

6

绝对是约翰所说的。getopts多次触发选项,所以如果你想使用第二种语法

./bootstrap.sh -bx -c 192.168.1.1 -c 192.168.1.2

它很容易实现 - 只需将您的-c参数推送到数组中以进行进一步处理,例如:

#!/bin/bash

b=0
x=0
c=()

while getopts ":bxc:" o; do
        case "${o}" in
                b) b=1 ;;
                x) x=1 ;;
                c) c+=( "${OPTARG}" ) ;;
                *) echo "usage()"; exit 1 ;;
        esac
done
shift $((OPTIND-1))

echo "b = ${b}"
echo "x = ${x}"
if (( ${#c} > 0 )); then
        for ip in "${c[@]}"; do
                ips="${ips}${ip}, "
        done
        echo "IPs = ${ips%??}"
fi
if (( $# > 0 )); then
        echo "non-option arguments: $*"
fi

例子:

$  ./test.sh foo bar quux
b = 0
x = 0
non-option arguments: foo bar quux

$  ./test.sh -bx -c 192.168.1.1 -c 192.168.1.2 foo bar quux
b = 1
x = 1
IPs = 192.168.1.1, 192.168.1.2
non-option arguments: foo bar quux
于 2013-04-28T15:35:07.143 回答
5

您应该考虑在两种规范的 Unix 命令行语法之间进行选择:

./bootstrap.sh -bx 192.168.1.1 192.168.1.2

也就是说,-b 和 -x 都没有参数,脚本将 IP 地址作为位置参数(任意数量)。

或者:

./bootstrap.sh -bx -c 192.168.1.1 -c 192.168.1.2

也就是说,-c 带一个参数,并且可以多次使用。这是非常传统的,在您说它丑陋或重复之前,请注意 Bash 或类似的 shell 将允许您使用与您最初建议的非常相似的速记:

./bootstrap.sh -bx -c={192.168.1.1,192.168.1.2}

shell 将扩展它,使实际调用与前面的示例相同。因此,如果您假设带有参数的常规 -c 选项,您的 shell 将“免费”支持上述内容。

请抵制发明新语法的诱惑,例如“-g foo,bar”,您可以在其中以某种应用程序指定的方式解析参数。这种方法不太适合与标准 Unix 工具(如xargs.

于 2013-04-28T09:28:55.360 回答