除非以某种方式指定选项,否则bash getopts会忽略选项

时间:2017-07-08 14:46:50

标签: bash getopts

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

以下代码段可以获得两个选项:

  • 调试 -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 在选项列表中 -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

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

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

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

将移位移出循环。 OPTIND是原始arg向量的绝对索引。在循环之后进行一次移位