getopts를 사용하여 변수 설정하기

getopts를 사용하여 변수 설정하기

bash 함수의 매개변수를 구문 분석하기 위해 getopts를 사용하고 싶습니다.

while getopts ${shortopts} arg; do

그런데 변수 값을 설정하는 데 문제가 있습니다. 호출되거나 myfunc -v8myfunc -v 8설정될 vb예상 값입니다 8.

myfunc -v 8
vb, arg:   ;  OPTARG: 8
vb: 8

그러나 명령을 다시 실행 myfunc -v 21하면

myfunc -v 21
vb: 1

이것이 옵션을 처리하는 방법입니다.

myfunc
{
  local vb=1

  local arg
  local shortopts="Vuhv:"

  while getopts ${shortopts} arg; do
    case ${arg} in
      # ........................................................
      ("V")
        printf "%s\n" "V01 Jul 2021 Wk27"
        return
        ;;
      ("u")
        printf "%s\n" "-V, -u, -h"
        return
        ;;
      ("h")
        printf "%s\n" "Prints status returned by getopt."
        printf "%s\n" "-V  Displays version"
        printf "%s\n" "-u  Displays usage"
        printf "%s\n" "-h  Displays help."
        printf "%s\n" "-v, -vNUM  Sets verbosity level."

        printf "%s\n" "Example: getopt-status --"
        return
        ;;
      ("v")
        vb="$OPTARG" 
        printf '%s\n' "vb, arg: $arg  ;  OPTARG: $OPTARG"
        ;;
      :)
        echo "Current argument value, OPTARG: -$OPTARG" >&2
        echo "Must supply an argument to -$OPTARG" >&2
        ;;
      ?)
        printf "%s\n" "Invalid option, OPTARG: $OPTARG"
        ;;
    esac
  done

  echo "vb: $vb"

}

답변1

ilkkachu와 다른 사람들이 언급했듯이 거기에는 몇 가지 버그가 있습니다. 함수의 종료 코드가 반환되므로 함수 내에서 작동 return합니다 .localreturn

다음은 아이디어를 제공하는 최소한의 예입니다.

#!/usr/bin/env bash

die(){ echo >&2 "$@"; exit 1; }
usage(){ echo >&2 "usage: $0 [-u] [-v num] "; exit 0; }

shortopts=":Vuhv:"
while getopts "$shortopts" opt; do
        case $opt in
        u)      usage ;;
        v)      case $OPTARG in
                ''|*[!-0-9]*) die "invalid number $OPTARG" ;;
                *) val=$OPTARG ;;
                esac
                ;;
        :)      die "argument needed to -$OPTARG" ;;
        *)      die "invalid switch -$OPTARG" ;;
        esac
done
shift $((OPTIND - 1))

echo value="$val"

몇 가지 참고사항:

옵션 문자열의 첫 번째 문자가 (콜론)인 경우, 앞에 옵션 문자가 없기 때문에 일반적으로 의미가 없으며, getopts는 "자동 오류 보고 모드"로 전환합니다. 효율적인 스크립트에서는 성가신 메시지로 방해받지 않고 오류를 직접 처리할 수 있으므로 일반적으로 원하는 것입니다.

더보기:https://wiki.bash-hackers.org/howto/getopts_tutorial

답변2

getopts함수에 사용될 때,~ 해야 하다OPTARG특히 현지화 OPTIND.

넌 할 수있어

myfunc() {
    local OPTIND OPTARG
    ...

getopts초기화를 담당합니다 .

관련 정보