getopts不會連續調用兩次?

[英]getopts won't call twice in a row?


For some reason the options work fine the first call of lib_progress_bar -c "@" -u "_" 0 100, but on the second call and beyond everything is default because it seems like getopts c:u:d:p:s:%:m: flag isn't true the second time around, or atleast the case is never executed when I used set -x

由於某種原因選擇工作的第一次調用lib_progress_bar - c - u“@”“_”0 100,但在第二個電話,超出一切違約,因為似乎getopt c:你:d:p:s:%:m:國旗不是真的第二次,或者至少不會執行當我使用- 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;

2 个解决方案

#1


14  

Just add:

添加:

local OPTIND

at the top of your function.

在函數的頂端。

#2


13  

To explain why Dennis's answer works, see the bash man page (search for getopts):

要解釋為什么丹尼斯的答案是有效的,請看bash手冊頁(尋找getopts):

OPTIND is initialized to 1 each time the shell or a shell script is invoked.

每次調用shell或shell腳本時,OPTIND初始化為1。

The shell does not reset OPTIND automatically; it must be manually reset between multiple calls to getopts within the same shell invocation if a new set of parameters is to be used.

外殼不會自動重置OPTIND;如果要使用一組新的參數,則必須在同一shell調用中對getopts的多個調用之間手動重置。

This is how getopts can process multiple options.

這就是getopts如何處理多個選項。

If getopts didn't maintain global state in the OPTIND variable, each call to getopts in your while loop would keep processing $1, and never advance to the next argument.

如果getopts在OPTIND變量中沒有保持全局狀態,那么每次對您的while循環中的getopts的調用都將繼續處理$1,並且永遠不會進入下一個參數。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2011/02/19/730088c8fe69ea758771d2d2d751e711.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com