getopts, getopt로 option 컨트롤

markyang92·2021년 6월 29일
0

shell-script

목록 보기
17/20

참고: https://mug896.github.io/bash-shell/getopts.html

  • 기본적으로 쉘/함수의 아규먼트는 $1, $2 로 접근한다.

short 옵션 특징

  • -로 시작하는 short한 옵션
    • -p
  • 여러 가지 방법으로 사용 가능
  • getopts명령을 이용하지 않고 직접 옵션을 해석해 처리하면, 옵션 처리에 스크립트가 매우 복잡해질 수 있음

  1. 기본 옵션 사용
$ cmd -a -b -c

  1. 순서에 상관 없음
$ cmd -abc
$ cmd -b -ac

  1. 옵션 argument를 가질 수 있음
$ cmd -a xxx -b -c yyy

  1. 옵션 argument를 붙여 쓸 수 있음
$ cmd -axxx -bcyyy

  1. 옵션 구분자 '--'가 올 경우 우측에 있는 값은 옵션으로 해석하면 안된다.

long 옵션 특징

  • --가 붙는 long 옵션
    • --posix, --wrning level

getopts

option 넣기

  • while + getopts
    • 옵션은 $opt 에 loop 하나씩 들어간다.
  • 아래는 Usage: ./shell [-aht]이다.
    • 옵션의 argument 를 가지지 못하고, 필수 옵션이 아니다.
#!/bin/bash

# ===== main ===== #
while getopts "ahd" opt; do
    case $opt in
        a)
            -a 옵션이 들어오면 할 일
            ;;
        h)
            -h 옵션이 들어오면 할 일
            ;;
        t)
            -t 옵션이 들어오면 할 일
            ;;
        \?)	# 지정이외 옵션은 이 문자로 할당된다.
            echo $@ is not valid option
            exit 0
            ;;            
    esac
done

  • 옵션을 강제설정 하려면 재량껏 알아서해라
#!/bin/bash

# ===== main ===== #
while getopts "ahd" opt; do
    case $opt in
        a)
            -a 옵션이 들어오면 할 일
            ;;
        h)
            -h 옵션이 들어오면 할 일
            ;;
        t)
            -t 옵션이 들어오면 할 일
            ;;
        \?)	# 지정이외 옵션은 이 문자로 할당된다.
            echo $@ is not valid option
            exit 0
            ;;
    esac
done

[ $# -eq 0 ] && echo "None of option is inserted"
# option 갯수가 0개 들어오면 윗 문장 실행

argument

  • while + getopts를 사용하면서 argument 를 사용하고 싶다.

  • argument
  1. option: (Verbose mode)
  2. :option: (Silent mode) 지정하여 사용한다.

  • e.g.,
    • while getopts "a:hd" opt; do (a옵션은 argument(verbose mode)를 가지고, 나머지 옵션은 그냥 옵션만 가진다)
    • while getopts ":a:hd" opt; do (a옵션은 argument(silent mode)를 가지고, 나머지 옵션은 그냥 옵션만 가진다)
  • 주의점!!!!!
    • :a:hd
      • a만 argument를 요구(silent mode)
    • h:a:d
      • 의도: a를 argument 요구(silent mode) 하고 싶음
      • 실제 실행: h argument 요구(verbose mode), a argument요구(verbose mode)

a: Verbose mode

  • getopts "a:"a 옵션에 콜론(:)을 붙여 인자를 요구케 함 (Verbose mode)
  • 옵션은 $opt로 들어간다.
  • argument는 $OPTARG로 들어간다.
    • 예: -a "hello world"
      • $opt: 'a'
      • $OPTARG: "hello world"
Verbose modeDescription
invalid 옵션 사용 시
즉 "a:bc" 만 허용 하는데, -d 같은 것 넣은 경우
opt 값을 ?문자로 설정하고 OPTARG 값은 unset. 오류 메시지 출력
argument 안 넣었을 때
즉, "a:bc"로 설정해 -a 'arg' 넣어야하는데 -a 만 넣은 경우
opt 값을 ?문자로 설정하고 OPTARG 값은 unset. 오류 메시지 출력

  1. $ ./script.sh -a : argument 안 넣음
    1-1. 아래와 같은 에러 메시지 출력은 기본
    1-2. $opt 문자를 \?로 처리해 에러 처리
#!/bin/bash

# ==== main ==== #
while getopts "a:bc" opt; do
    case $opt in
        a)
            echo "-a triggered, argument: ${OPTARG}"
            ;;
        b)
            echo "-b triggered"
            ;;
        c)
            echo "-c triggered"
            ;;
        \?)
            echo "invalid option | not insterted argument"
            ;;
    esac
done

:a: Silent mode

  • getopts ":a:"a 옵션 콜론(:)을 붙여 더 세밀한 error handling이 가능하게 한다. (Silent mode)
Silent modeDescription
invalid 옵션 사용 시
즉 "a:bc" 만 허용 하는데, -d 같은 것 넣은 경우
opt 값을 ?문자로 설정하고 OPTARG 값은 해당 옵션 문자로 설정
argument 안 넣었을 때
즉, "a:bc"로 설정해 -a 'arg' 넣어야하는데 -a 만 넣은 경우
opt 값을 :문자로 설정하고 OPTARG 값은 해당 옵션 문자로 설정
  • silent mode는 아래와같이 더 세부적인 에러 핸들링이 가능하다.

argument '지정'

  • -s <45|90> -p <string> 옵션을 사용해야하는 프로그램


long 옵션의 처리

getopt 사용

  • /usr/bin/getopt 를 사용한다.
  • 위의 getopts와 헷갈리지 말 것!
  1. short option은 -o를 사용하여 아래와 같이 사용한다.
    1.1 option은 그냥 나열하면된다.
    1.2 argument를 가지는 옵션은 :를 뒤에 붙인다.
getopt -o a:bc # 위의 getopts와 똑같다. -a, -b, -c 를 옵션으로 가지고 -a는 argument가 있다.

  1. long option은 -l을 사용하고, ,로 구분한다.
    2.1 option은 ,로 구분한다.
    2.1 argument를 가지는 옵션은 :를 뒤에 붙인다.
getopt -l help,path:,name:
# --help
# --path 'argument'    --path='argument'
# --name 'argument'    --name='argument'

  1. short, long 공통
    3.1 마지막에 -- "$@"를 붙인다.
    3.2 invalid option이나 argument가 빠진 경우 오류메시지를 출력한다.

short, long 혼용 예

#!/bin/bash

options=$( getopt -o a:bc -l help,path:,name: -- "$@" )
echo "$options"

  1. invalid option
$ ./test.sh -x
getopt: invalid option -- 'x'

$ ./test.sh --xxx
getopt: unrecognized option '--xxx'

  1. require an argument
$ ./test.sh -a
getopt: option requires an argument -- 'a'

$ ./test.sh --name
getopt: option '--name' requires an argument

case로 분류

#!/bin/bash

if ! options=$( getopt -o a:bc -l help,path:,name: -- "$@" )
then 
    echo "ERROR: print usage"
    exit 1
fi

eval set -- "$options"

while true; do
    case "$1" in
        -h|--help)
            echo >&2 "$1 was triggerd!"
            shift ;;
        -p|--path)
            echo >&2 "$1 was triggered!, OPTARG: $2"
            shift 2 ;; # 옵션이 argument가 있으므로 shift 2
        -n|--name)
            echo >&2 "$1 was triggered!, OPTARG: $2"
            shift 2 ;;
        --aaa)
            echo >& "$1 was triggered!"
            shift ;;
        --)
            shift
            break
    esac
done

echo -------------
echo "$@"

사용

$ ./test.sh -h hello.c -p /usr/bin --name='foo bar' --aaa -- --bbb
-h was triggered!
-p was triggered!, OPTARG: /usr/bin
--name was triggered!, OPTARG: foo bar
--aaa was triggered!
-----------------
hello.c --bbb

redirection, PIPE 로 opt 넘기기

  • redirection, pipe를 사용하면 stdin으로 읽기 때문에 read 명령을 사용한다.
profile
우츠우츠

0개의 댓글