【问题标题】:When I use getopts in a Bash function, why does it ignore arguments on the second call?当我在 Bash 函数中使用 getopts 时,为什么它会忽略第二次调用的参数?
【发布时间】:2014-06-08 20:39:01
【问题描述】:

下面是我的代码

function waitTillGWState 
{
    if [[ $# -lt 6 ]] ; then
      echo "$FUNCNAME:: Wrong parameter specified. Exiting."
      exit 1
    fi
local Fname1
local fset
local state
local lhost

echo "$# $@"
waitTillGWState_Usage() { echo "waitTillGWState: [-F <Fname1> -t <Fname2> -S <state> -h <host>]" 1>&2; exit; }
while getopts F:t:S:h: x; do
    case ${x} in
    F)
        Fname1="${OPTARG}"
        echo "Value of Fname1 is $Fname1"
        ;;
    t)
        Fname2="${OPTARG}"
        echo "Value of Fname2 is $Fname2"
        ;;
    S)
        state="${OPTARG}"
        echo "Value of state is $state"
        ;;
    h)
        lhost="${OPTARG}"
        echo "Value of lhost is $lhost"
        ;;
    *)
       waitTillGWState_Usage
        ;;
esac
done

shift $((OPTIND-1))
echo "Values are  $Fname1 $Fname2 $state $lhost"

if [[ -z "${lhost}" ]] ; then
    lhost=`hostname`
fi

echo  "Values are  $Fname1 $Fname2 $state $lhost"

return 0
}
waitTillGWState -F Fname1 -t X4 -S Active
waitTillGWState -F Fname1 -t X4 -S Disconnectecd

现在,当我运行它时,它第一次完美运行。但第二次这失去了价值。

+ waitTillGWState -F Fname1 -t X4 -S Active
+ [[ 6 -lt 6 ]]
+ local Fname1
+ local fset
+ local state
+ local lhost
+ echo '6 -F' Fname1 -t X4 -S Active
6 -F Fname1 -t X4 -S Active
+ getopts F:t:S:h: x
+ case ${x} in
+ Fname1=Fname1
+ echo 'Value of Fname1 is Fname1'
Value of Fname1 is Fname1
+ getopts F:t:S:h: x
+ case ${x} in
+ Fname2=X4
+ echo 'Value of Fname2 is X4'
Value of Fname2 is X4
+ getopts F:t:S:h: x
+ case ${x} in
+ state=Active
+ echo 'Value of state is Active'
Value of state is Active
+ getopts F:t:S:h: x
+ shift 6
+ echo 'Values are  Fname1 X4 Active '
Values are  Fname1 X4 Active
+ [[ -z '' ]]
++ hostname
+ lhost=p7fbn11
+ echo 'Values are  Fname1 X4 Active p7fbn11'
Values are  Fname1 X4 Active p7fbn11
+ return 0
+ waitTillGWState -F Fname1 -t X4 -S Disconnectecd
+ [[ 6 -lt 6 ]]
+ local Fname1
+ local fset
+ local state
+ local lhost
+ echo '6 -F' Fname1 -t X4 -S Disconnectecd
6 -F Fname1 -t X4 -S Disconnectecd
+ getopts F:t:S:h: x
+ shift 6
+ echo 'Values are   X4  '
Values are   X4
+ [[ -z '' ]]
++ hostname
+ lhost=myhost1
+ echo 'Values are   X4      myhost1'
Values are   X4  myhost1
+ return 0

所以,我在第二次调用时丢失了值。

有人知道为什么会这样吗?

我也试过不使用局部变量。

【问题讨论】:

  • 可选参数,顾名思义,是可选的。有时要求一个可选参数很诱人,但这样做通常是一个坏主意,而不仅仅是因为它违反了参数处理的准则。即使您决定需要可选参数,仅检查参数计数也不是一个很好的方法。如果用户调用waitTillGWState -F file1 -F file2 -F file3怎么办?
  • 我同意。这是照顾。谢谢提醒。

标签: bash getopts


【解决方案1】:

基本问题是getopts 使用全局变量OPTIND 来跟踪其进度。 OPTIND 在 shell 启动时设置为 1,getopts 使用它来识别应该解析哪个参数。一旦getopt 扫描了所有选项,OPTIND 就是第一个位置参数的索引,这就是shift $((OPTIND-1)) 起作用的原因。

正如bash manual 所说:

shell 不会自动重置OPTIND;如果要使用一组新参数,则必须在同一 shell 调用内多次调用 getopts 之间手动重置它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 2013-04-08
    • 2016-03-03
    • 1970-01-01
    相关资源
    最近更新 更多