shell --getopts

getopts 是一个在Bash和其他兼容的shell中用于解析命令行选项的内置命令,它可以让脚本方便地处理用户传入的各种选项和参数。

1. 基本语法

getopts optstring name [args]
  • optstring:由合法选项字符组成的字符串。如果某个选项字符后面跟着一个冒号 :,表示该选项需要一个参数;如果冒号在 optstring 开头,则表示开启错误抑制模式。
  • name:用于存储当前解析到的选项字符的变量名。
  • [args]:可选参数,指定要解析的参数列表。若省略,默认使用 $@(即脚本接收到的所有命令行参数)。

2. 返回值

  • getopts 执行成功时返回 0(表示真),意味着还有选项需要解析。
  • 当所有选项都解析完毕后,返回 1(表示假),用于终止循环。

3. 内置变量

  • OPTARG:当某个选项需要参数时,getopts 会将该参数赋值给 OPTARG 变量。
  • OPTIND:记录当前解析到的参数的索引位置。初始值为 1,每解析一个选项,OPTIND 就会递增。在处理完选项后,可以使用 shift $((OPTIND - 1)) 来跳过已解析的选项,使 $1 指向第一个非选项参数。
  • OPTERR:用于控制是否显示 getopts 的错误信息。默认值为 1,表示显示错误信息;若设置为 0,则不显示。

4. 选项字符规则

  • 无参数选项:在 optstring 中,单个字符表示该选项不需要参数。例如,"abc" 表示支持 -a-b-c 三个无参数选项。
  • 带参数选项:在 optstring 中,字符后面跟一个冒号 : 表示该选项需要一个参数。例如,"a:b" 表示 -a 选项需要一个参数,-b 选项不需要参数。
  • 选项组:多个选项可以连写,只要它们都是无参数选项。例如,对于 optstring"abc"-abc 等同于 -a -b -c

5. 错误处理

  • 无效选项:当用户输入的选项不在 optstring 中时,getopts 会将 name 变量设置为 ?,并默认输出错误信息。可以通过将 OPTERR 设置为 0 来抑制错误信息,然后在脚本中自行处理。
  • 缺少参数:当需要参数的选项没有提供参数时,getopts 在不同的shell环境下有不同的行为。在Bash中,如果 optstring 开头没有冒号,getopts 会将 name 变量设置为 ?,并输出错误信息;如果 optstring 开头有冒号,getopts 会将 name 变量设置为 :,表示缺少参数。

6. 示例代码及详细解释

#!/bin/bash

# 抑制 getopts 的错误信息
OPTERR=0

# 定义选项字符串,a 无参数,b 有参数
optstring=":a:b"

while getopts "$optstring" opt; do
    case $opt in
        a)
            echo "选项 -a 已指定"
            ;;
        b)
            echo "选项 -b 已指定,参数为 $OPTARG"
            ;;
        \?)
            echo "无效的选项: -$OPTARG" >&2
            ;;
        :)
            echo "选项 -$OPTARG 需要一个参数" >&2
            ;;
    esac
done

# 移动参数指针,跳过已解析的选项
shift $((OPTIND - 1))

# 处理剩余的非选项参数
if [ $# -gt 0 ]; then
    echo "剩余的非选项参数:"
    for arg in "$@"; do
        echo "  $arg"
    done
else
    echo "没有剩余的非选项参数"
fi

代码解释

  1. OPTERR=0:将 OPTERR 设置为 0,抑制 getopts 的默认错误信息。
  2. optstring=":a:b"optstring 开头的冒号开启错误抑制模式,a 是无参数选项,b 是带参数选项。
  3. while getopts "$optstring" opt; do ... done:使用 while 循环调用 getopts 解析选项,直到所有选项都解析完毕。
  4. case $opt in ... esac:根据不同的选项字符执行不同的操作。
    • \?):处理无效选项,输出错误信息。
    • :):处理缺少参数的情况,输出错误信息。
  5. shift $((OPTIND - 1)):跳过已解析的选项,使 $1 指向第一个非选项参数。
  6. 处理剩余的非选项参数:使用 for 循环遍历剩余的非选项参数并输出。

7. 长选项处理

getopts 本身不支持长选项(如 --help),但可以通过一些技巧来模拟处理长选项。例如:

#!/bin/bash

while [ $# -gt 0 ]; do
    case $1 in
        --help)
            echo "这是帮助信息"
            ;;
        --verbose)
            echo "启用详细模式"
            ;;
        *)
            break
            ;;
    esac
    shift
done

# 处理剩余的非选项参数
if [ $# -gt 0 ]; then
    echo "剩余的非选项参数:"
    for arg in "$@"; do
        echo "  $arg"
    done
else
    echo "没有剩余的非选项参数"
fi

8. 注意事项

  • 选项顺序getopts 会按顺序解析选项,遇到第一个非选项参数时停止解析。因此,非选项参数应放在选项之后。
  • 参数传递:带参数的选项和其参数之间可以有空格,也可以没有空格。例如,-b value-bvalue 都可以被正确解析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值