인수와 플래그를 무작위 순서로 취하는 함수를 작성하는 방법은 무엇입니까?

인수와 플래그를 무작위 순서로 취하는 함수를 작성하는 방법은 무엇입니까?

저는 쉘을 처음 접했고 일반 인수를 받아들이고 제공된 모든 플래그를 구문 분석하는 사용자 정의 함수를 작성하려고 합니다.

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.

답변1

예: 함수에서 호출하기 전에 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'

관련 정보