본문으로 건너뛰기

ShellScript getopt

getopts

$ script.sh a  b  c  d
$0 $1 $2 $3 $4
-------------------
$@

getopts 명령어는 옵션과 해당 인자를 파싱하는데 사용되는 POSIX 쉘 빌트인 명령어입니다.

getopts <optString> option [parameters="$@"]
echo $option
echo $OPTARG
echo $OPTIND # 다음 인자의 인덱스

getopt

getopts의 단점은

  • 짧은 옵션만 파싱 가능합니다
  • 옵션이 아닌 인자 다음에 오는 옵션을 파싱할 수 없습니다

getopt 명령어는 옵션과 옵션이 아닌 인자를 재정렬하고, 짧은 옵션과 긴 옵션을 모두 파싱할 수 있습니다.

getopt -o <shortOptString> -l <longOptString> -- <parameters>
  • -n | --name <name>: 프로그램 이름을 설정합니다
경고

Mac OS에서는 gnu-getopt를 설치하거나 GNU getopt가 없는 경우에 대한 처리를 해야합니다.

if ! getopt -T >/dev/null; then
# GNU getopt가 설치된 경우
options=$(getopt ...)
else
# GNU getopt가 설치 안된 경우
fi

shortOptString

<option1>[:][<option2>[:]...]

-a, -b를 파싱하고 싶으면, shortOptStringab를 설정하면 됩니다. 만약 -a 옵션이 값을 받아야 하면 :을 사용하여 a:b로 설정하면 됩니다. getopt- 이후에 하나의 문자열만 인식하므로 -a a_arg-aa_arg는 같은 표현으로 간주합니다.

Example

set -- -aa_arg -b asdf \
&& getopt -o a:b -- "$@"
 -a 'a_arg' -b -- 'asdf'

longOptString

<option1>[:][,<option2>[:],...]

--foo --bar를 파싱하고 싶으면, longOptStringfoo,bar를 설정하면 됩니다. 만약 --foo 옵션이 값을 받아야 하면, :을 사용하여 foo:,bar로 설정하면 됩니다. getopt--foo=arg--foo arg를 같은 표현으로 간주합니다.

Example

set -- --foo arg --bar \
&& getopt -o "" -l foo:,bar -- "$@"

Example script

#!/bin/sh

set -e

RED=$(tput setaf 1)
BOLD=$(tput bold)
DEFAULT=$(tput sgr0)

COMMAND=$(basename "$0")

help_msg() {
cat <<END
사용법:
$COMMAND [옵션] [인자]

옵션:
-a, --aaa
-b, --bbb <값>
-c, --ccc

예시:
END
}

if ! getopt -T >/dev/null; then
options=$(getopt \
-o ab:ch \
-l aaa,bbb:,ccc,help \
-n "$COMMAND" \
-- "$@")
else
eval set -- "$(echo "$@" | sed -E 's/--([a-z])[a-z]*/-\1/g')"
options=$(getopt \
ab:ch \
"$@")
fi

IS_PARSED=$?

if [ $# -eq 0 ] || [ $IS_PARSED -ne 0 ]; then
printf "%s\n" "${RED}${BOLD}$(help_msg)${DEFAULT}" >&2
exit 1
fi

eval set -- "$options"

while true; do
case "$1" in
-a | --aaa)
echo "$1"
shift
;;
-b | --bbb)
echo "$1" "$2"
shift 2
;;
-c | --ccc)
echo "$1"
shift
;;
-h | --help)
help_msg
exit 0
;;
--)
echo "$@"
shift $#
break
;;
esac
done