getopts不会连续调用两次?

由于某些原因,这些选项可以正常工作,第一次调用lib_progress_bar -c "@" -u "_" 0 100 ,但是在第二次调用之后,一切都是默认的,因为它看起来像getopts c:u:d:p:s:%:m: flag第二次不是真的,或者至less在我使用set -x时候永远不会执行

 #!/bin/bash lib_progress_bar() { local current=0 local max=100 local completed_char="#" local uncompleted_char="." local decimal=1 local prefix=" [" local suffix="]" local percent_sign="%" local max_width=$(tput cols) local complete remain subtraction width atleast percent chars local padding=3 while getopts c:u:d:p:s:%:m: flag; do case "$flag" in c) completed_char="$OPTARG";; u) uncompleted_char="$OPTARG";; d) decimal="$OPTARG";; p) prefix="$OPTARG";; s) suffix="$OPTARG";; %) percent_sign="$OPTARG";; m) max_width="$OPTARG";; esac done shift $((OPTIND-1)) current=${1:-$current} max=${2:-$max} if (( decimal > 0 )); then (( padding = padding + decimal + 1 )) fi let subtraction=${#completed_char}+${#prefix}+${#suffix}+padding+${#percent_sign} let width=max_width-subtraction if (( width < 5 )); then (( atleast = 5 + subtraction )) echo >&2 "the max_width of ($max_width) is too small, must be atleast $atleast" return 1 fi if (( current > max ));then echo >&2 "current value must be smaller than max. value" return 1 fi percent=$(awk -v "f=%${padding}.${decimal}f" -v "c=$current" -v "m=$max" 'BEGIN{printf('f', c / m * 100)}') (( chars = current * width / max)) # sprintf n zeros into the var named as the arg to -v printf -v complete '%0*.*d' '' "$chars" '' printf -v remain '%0*.*d' '' "$((width - chars))" '' # replace the zeros with the desired char complete=${complete//0/"$completed_char"} remain=${remain//0/"$uncompleted_char"} printf '%s%s%s%s %s%s\r' "$prefix" "$complete" "$remain" "$suffix" "$percent" "$percent_sign" if (( current >= max )); then echo "" fi } lib_progress_bar -c "@" -u "_" 0 100 echo lib_progress_bar -c "@" -u "_" 25 100 echo lib_progress_bar -c "@" -u "_" 50 100 echo exit; 

Solutions Collecting From Web of "getopts不会连续调用两次?"

只需添加:

 local OPTIND 

在你的函数的顶部。

要解释为什么Dennis的答案有效,请参阅bash手册页(搜索getopts ):

每次调用shell或shell脚本时,OPTIND都被初始化为1。

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

这是getopts如何处理多个选项。

如果getopts没有在OPTIND变量中维护全局状态,那么在while循环中每次调用getopts将继续处理$1 ,并且不会前进到下一个参数。