Bash

如何編寫一個以隨機順序獲取參數和標誌的函式?

  • August 29, 2022

我是 shell 新手,我正在嘗試編寫一個自定義函式,該函式接受正常參數,並解析提供的任何標誌。

test_it() {
 flag1="false"
 flag2="false"

 while getopts "ab" opt; do
   case ${opt} in
   a) flag1="true" ;;
   b) flag2="true" ;;
   *) break ;;
   esac
 done
 echo $flag1 $flag2
 shift "$(($OPTIND - 1))"
 echo "Custom param: $1"
}

但是,如果我在標誌之後提供自定義參數,則此功能只能按我的意願工作。如果我要在標誌之前提供自定義參數,它不會解析標誌。

> test_it -ab foo
true true
Custom param: foo
> test_it foo -ab
false false
Custom param: foo
> test_it -a foo -b
true false
Custom param: foo

有沒有一種方法可以讓標誌和參數得到正確解析,而不管順序如何?換句話說,它應該true true在所有這三種情況下都回顯這兩個標誌,因為它們是在函式呼叫期間的某個時刻被呼叫的?這應該是可能的,因為我觀察到函式喜歡那樣rsync做。

是:在函式中,在呼叫之前while getopts,添加

local OPTIND OPTARG

這將每次將“計數器”重置為 0。


另請注意,這while getopts將在第一個非選項處停止。如果你想test foo -ab工作,你需要使用getopt(1)getopt範例腳本

test_it() {
   local tmp flag1=false flag2=false
   tmp=$(getopt -o 'ab' -n "$FUNCNAME" -- "$@")
   
   local rc=$?
   ((rc == 0)) || return $rc
   
   eval set -- "$tmp"
   
   while true; do
       case "$1" in
           '-a') flag1=true
                 shift
                 ;;
           '-b') flag2=true
                 shift
                 ;;
           '--') shift
                 break
                 ;;
           *)    echo Internal Error >&2
                 return 1
                 ;;
       esac
   done

   declare -p flag1 flag2
   echo "Remaining params:"
   printf "%s\n" "$@"
}
$ test_it foo -a bar -b
declare -- flag1="true"
declare -- flag2="true"
Remaining params:
foo
bar

$ test_it -a quz
declare -- flag1="true"
declare -- flag2="false"
Remaining params:
quz

$ test_it baz -b
declare -- flag1="false"
declare -- flag2="true"
Remaining params:
baz

$ test_it -c
test_it: invalid option -- c

$ test_it baz --ab
test_it: unrecognized option `--ab'

引用自:https://unix.stackexchange.com/questions/715401