[shell script] 옵션 기능 구현하기

HYEOB KIM·2022년 4월 25일
0

Shell

목록 보기
41/71

쉘 스크립트 파일을 실행할 때 옵션 기능을 구현하는 방법에 대해 실습해봅시다.

우리가 만든 쉘 스크립트 파일을 하나의 명령어를 실행한다고 생각해봅시다.

파라미터로 옵션을 주게 되면 해당 옵션에 대한 기능을 실행할 수 있도록 쉘 스크립트를 작성해 보는 실습을 진행해 보겠습니다.

getopt

매개변수를 처리할 때 가장 편리한 명령어는 getopt입니다.

getopt optstring parameters
  • optstring에는 유효한 옵션 문자를 정의합니다.
    예를 들어, abcd 라면 커맨드라인은 유효한 옵션으로 -a, -b, -c, -d를 가진다는 의미입니다.

  • : 문자는 해당 옵션이 매개변수를 꼭 가진다는 의미입니다.
    예를 들어, ab:cd라면 -b는 꼭 매개변수를 가진다는 의미입니다.

아래와 같이 입력해서 결과를 실행해봅시다.

$ getopt ab:cd -a -b test1 -cd test 2
 -a -b test1 -c -d -- test 2

위와 같이 parameters에 대해서 파싱된 결과를 반환합니다.

이를 빈 칸을 기준으로 분리해서 하나씩 조회해 해당 옵션에 대한 기능을 스크립트를 통해 작성할 수 있습니다.
(해당 기능은 아래에 set --를 이용해서 구현할 수 있습니다)

출력값에서 --를 기준으로 optstringparameter가 구분됩니다.

💡참고
optstring으로 지정하지 않은 옵션을 파라미터로 주게 되면 에러가 발생합니다.

$ getopt ab:cd -a -b test1 -cde test 2
getopt: invalid option -- 'e'
 -a -b test1 -c -d -- test 2

오류 메시지를 무시하고 싶다면 -q 옵션을 줄 수 있습니다.

$ getopt -q ab:cd -a -b test1 -cde test 2
 -a -b 'test1' -c -d -- 'test' '2'

set --

getopt를 통해 스크립트를 작성할 때 유용하게 사용될 수 있는 명령어는 set -- parameters입니다.

set --는 뒤에 오는 파라미터를 커맨드라인의 파라미터로 대신하도록 기능합니다.

$ cat test1
#!/bin/bash
echo $(getopt ab:cd "$@")

$ ./test1 -a -b test1 -cd test2 test3
-a -b test1 -c -d -- test2 test3

만약 set -- $(getopt ab:cd "$@")로 작성한다면,
해당 스크립트를 실행할 때 ./test1 -a -b test1 -cd test2 test3이 아닌,
./test1 -a -b test1 -c -d -- test2 test3을 실행했다고 인식하게 됩니다.

예를 들어, $4를 조회하면 -cd가 아닌 -c가 조회됩니다.

$ cat test1
#!/bin/bash
set -- $(getopt ab:cd "$@")
for word in "$@"
do
        echo $word
done

$ ./test1 -a -b test1 -cd test2 test3
-a
-b
test1
-c
-d
--
test2
test3
  • set -- $(getopt ab:cd "$@")를 이용해서 커맨드라인의 파라미터를 변경해주고, 반복문을 이용해 $@를 조회하면 -a -b test1 -c -d -- test2 test3를 빈 칸을 기준으로 분리해서 하나씩 참조하게 되는 겁니다.

반복문, case, shift를 이용하기

getopt, set --와 함께 반복문, case, shift를 이용해서 커맨드라인의 옵션에 기능을 부여해봅시다.

$ cat test1
#!/bin/bash
set -- $(getopt ab:cd "$@")
while [ -n "$1" ]
do
        case "$1" in
                -a) echo "Found the -a option";;
                -b) param=$2
                        echo "Found the -b option, with parameter value $param"
                        shift;;
                -c) echo "Found the -c option";;
                -d) echo "Found the -d option";;
                --) shift
                        break;;
                *) echo "$1 is not an option";;
        esac
        shift
done

cnt=$#
for (( i=1; i<=cnt; i++))
do
        echo "parameter #$i: $1"
        shift
done

$ ./test1 -a -b test1 -cd test2 test3
Found the -a option
Found the -b option, with parameter value test1
Found the -c option
Found the -d option
parameter #1: test2
parameter #2: test3

💡코드 리뷰

  • case를 이용해서 옵션별 기능을 구현합니다.
  • shift를 이용해서 파라미터를 왼쪽으로 밀어서 $1, $2를 조회합니다.
  • 만약 파라미터를 필요로 하는 옵션을 만날 경우 case내에서 shift를 해줌으로써 2칸 왼쪽으로 밉니다.
profile
Devops Engineer

1개의 댓글

comment-user-thumbnail
2023년 10월 24일

혹시 그렇다면 set 명령어를 사용해서 명령어를 전처리할 수 있다고 이해하면 될까요? 좋은 글 감사합니다!

답글 달기