쉘 스크립트 파일을 실행할 때 옵션 기능을 구현하는 방법에 대해 실습해봅시다.
우리가 만든 쉘 스크립트 파일을 하나의 명령어를 실행한다고 생각해봅시다.
파라미터로 옵션
을 주게 되면 해당 옵션에 대한 기능을 실행할 수 있도록
쉘 스크립트를 작성해 보는 실습을 진행해 보겠습니다.
매개변수를 처리할 때 가장 편리한 명령어는 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 --
를 이용해서 구현할 수 있습니다)
출력값에서 --
를 기준으로 optstring
과 parameter
가 구분됩니다.
💡참고
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'
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
를 빈 칸을 기준으로 분리해서 하나씩 참조하게 되는 겁니다.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칸
왼쪽으로 밉니다.
혹시 그렇다면 set 명령어를 사용해서 명령어를 전처리할 수 있다고 이해하면 될까요? 좋은 글 감사합니다!