【问题标题】:bash getopts ignores options unless they are specified in a certain waybash getopts 忽略选项,除非它们以某种方式指定
【发布时间】:2017-12-12 17:34:31
【问题描述】:

Bash getopts 应该允许选项和参数不依赖于位置,如 tutorialsdocs 中所述。

下面的sn-p代码可以接收两个选项:

  • 需要参数的调试 -d 选项
  • 强制 -f 选项,不带参数。

我看到只有列出的第一个选项得到正确处理的奇怪行为。

#!/bin/bash

## Defaults 
DEBUG=INFO
forceOption=FALSE

## Usage
printUsage() {
    echo "  "    
    echo "USAGE: $0 [-d <DEBUG_LEVEL>] [ -f ]"
    echo "  "    
    exit 1
} 

#
## Manage options before start
# 

while getopts "hfd:" OPT
do 
    case $OPT in 
        h) printUsage ;;
        f) forceOption="TRUE" ;;
        d) debugLevel="$OPTARG" ;;
        *) printUsage ;;    
    esac
    shift `expr $OPTIND - 1`
done

if [ -n "$debugLevel" ] ; then
    DEBUG="$debugLevel"
fi

echo "DEBUG : $DEBUG"
echo "Force : $forceOption"

你可以看到下面的错误行为:

[rgulia$ ~] ./getopts.sh -d WARNING -f 
DEBUG : WARNING
Force : FALSE
[rgulia$ ~] ./getopts.sh -f -d WARNING  
DEBUG : INFO
Force : TRUE

代码在单独使用选项或如果 -f 在选项列表中的 -f 之前,它们彼此附加到 -d

[rgulia$ ~] ./getopts.sh -f
DEBUG : INFO
Force : TRUE
[rgulia$ ~] ./getopts.sh -d WARNING
DEBUG : WARNING
Force : FALSE
[rgulia$ ~] ./getopts.sh -fd WARNING  
DEBUG : WARNING
Force : TRUE

我的印象是,循环过早退出,因为当一个选项传递参数时它无法正确计算OptiNind。

我使用 printf 语句对 OPT、OPTARG 和 OPTIND 的值进行了一些跟踪,证实了这种理论,但我仍然不明白为什么会发生这种情况以及如何解决它。

有什么建议吗?

【问题讨论】:

    标签: bash getopts


    【解决方案1】:

    取消循环。 OPTIND 是原始 arg 向量的绝对索引。在循环之后执行一次移位

    【讨论】:

    • 你是对的!有用。我想我一直误解了 OPTIND 的含义。因此,getopts 会跟踪在循环中读取的选项和参数,并且 OPTIND 的递减只是为了让 shell 知道一旦处理了 -d 和 -f 后 arg 向量中还剩下多少个参数,对吧?
    • 是的。就我个人而言,我已经停止对 args 使用 getopts 样式。它被设计为简洁(当时“复制”太长,因此是“cp”)并且大多数其他主要操作系统(MSDOS,VMS,RSTS)使用command /option=value ..."#但Unix在路径名中使用“/”,所以它切换到-o value。扫描 args[] 以查找 option=value ... 形式的字符串非常容易(在脚本和程序中),您也可以使用在环境中设置的参数默认值。我的 2c
    • 非常感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 2015-10-26
    • 2015-07-16
    • 1970-01-01
    • 2018-02-24
    • 2017-03-06
    相关资源
    最近更新 更多