Bash 튜토리얼 시리즈에 이어서, 이전 글에서는 위치 매개변수(positional parameters)에 대해 다루었습니다. 이번 글에서는 실무에서 바로 활용할 수 있는 셸 스크립트 예제와 함께 Bash 특수 매개변수(special parameters)를 자세히 살펴보겠습니다.
이 글에서 다룰 주요 Bash 특수 매개변수는 다음과 같습니다: $*, $@, $#, $$, $!, $?, $-, $_
$* 과 $@ 의 차이점
위치 매개변수 전체 목록에 접근하려면 두 가지 특수 매개변수인 $*와 $@를 사용할 수 있습니다. 큰따옴표 밖에서는 이 둘이 동일하게 동작합니다. 즉, 둘 다 $1부터 시작하는 위치 매개변수 전체를 공백으로 구분하여 확장합니다.
하지만 큰따옴표 안에서는 차이가 발생합니다. 큰따옴표 안의 $*는 IFS(Internal Field Separator)의 첫 번째 문자로 구분된 하나의 문자열로 확장됩니다. 형식은 "$1c$2c$3..."과 같습니다.
반면 큰따옴표 안의 $@는 각 매개변수가 개별적으로 따옴표 처리된 것처럼 확장됩니다. 즉, "$1" "$2".."$N" 형태로 분리됩니다.
예제 1: $* 와 $@ 로 위치 매개변수 확장하기
이 예제는 $*와 $@에 담긴 값이 어떻게 다른지 보여줍니다.
먼저 아래와 같이 expan.sh 파일을 생성합니다.
$ cat expan.sh #!/bin/bash export IFS='-' cnt=1 # $* 에 담긴 데이터 출력 echo "Values of \"\$*\":" for arg in "$*" do echo "Arg #$cnt= $arg" let "cnt+=1" done cnt=1 # $@ 에 담긴 데이터 출력 echo "Values of \"\$@\":" for arg in "$@" do echo "Arg #$cnt= $arg" let "cnt+=1" done
다음으로 아래처럼 expan.sh를 실행하면 $*와 $@의 동작 방식을 확인할 수 있습니다.
$ ./expan.sh "This is" 2 3 Values of "$*": Arg #1= This is-2-3 Values of "$@": Arg #1= This is Arg #2= 2 Arg #3= 3
- 위 스크립트는 IFS(내부 필드 구분자) 값을 하이픈('-')으로 설정하여 내보냈습니다.
- 스크립트 expan.sh에는 세 개의 매개변수가 전달되었습니다. $1="This is", $2="2", $3="3" 입니다.
- 특수 매개변수 "$*"의 값을 출력하면 하나의 값만 반환되며, 이는 IFS로 구분된 전체 위치 매개변수입니다.
- 반면 "$@"는 각 매개변수를 별도의 단어로 분리하여 제공합니다.
예제 2: $# 으로 위치 매개변수 개수 세기
$#는 위치 매개변수의 개수를 십진수 숫자로 반환하는 특수 매개변수입니다. 인자 개수 검증에 매우 유용하게 활용됩니다.
먼저 아래와 같이 arithmetic.sh 파일을 생성합니다.
$ cat arithmetic.sh #!/bin/bash if [ $# -lt 2 ] then echo "Usage: $0 arg1 arg2" exit fi echo -e "\$1=$1" echo -e "\$2=$2" let add=$1+$2 let sub=$1-$2 let mul=$1*$2 let div=$1/$2 echo -e "Addition=$add\nSubtraction=$sub\nMultiplication=$mul\nDivision=$div\n"
위치 매개변수의 개수가 2개 미만이면 아래와 같이 사용법 안내 메시지가 출력됩니다.
$ ./arithemetic.sh 10 Usage: ./arithemetic.sh arg1 arg2
예제 3: 프로세스 관련 매개변수 — $$ 와 $!
특수 매개변수 $$는 현재 셸의 프로세스 ID(PID)를 반환합니다. $!는 가장 최근에 실행된 백그라운드 프로세스의 PID를 반환합니다.
다음 스크립트는 셸의 프로세스 ID와 마지막으로 실행한 백그라운드 프로세스 ID를 출력합니다.
$ cat proc.sh #!/bin/bash echo -e "Process ID=$$" sleep 1000 & echo -e "Background Process ID=$!"
이제 위 스크립트를 실행하고 출력되는 프로세스 ID를 확인해 보겠습니다.
$ ./proc.sh Process ID=9502 Background Process ID=9503 $ ps PID TTY TIME CMD 5970 pts/1 00:00:00 bash 9503 pts/1 00:00:00 sleep 9504 pts/1 00:00:00 ps $
예제 4: 기타 Bash 특수 매개변수 — $?, $-, $_
- $? : 가장 최근에 실행된 명령어의 종료 상태(exit status)를 반환합니다.
- $- : set 내장 명령어로 설정된 옵션들을 반환합니다.
- $_ : 이전 명령어의 마지막 인자를 반환합니다. 셸 시작 시에는 실행 중인 셸 스크립트의 절대 경로 파일명을 반환합니다.
$ cat others.sh #!/bin/bash echo -e "$_"; ## 실행 중인 파일의 절대 경로 /usr/local/bin/dbhome # 명령어 실행 # dbhome의 종료 상태 확인 if [ "$?" -ne "0" ]; then echo "Sorry, Command execution failed !" fi echo -e "$-"; # 설정된 옵션 - hB echo -e $_ # 이전 명령어의 마지막 인자
위 스크립트에서 마지막 echo 문인 "echo -e $_"($_ 언더스코어) 역시 hB를 출력하는데, 이는 이전 명령어의 마지막 인자 값입니다. 즉, $_는 확장(expansion) 이후의 값을 반환한다는 점을 알 수 있습니다.
$ ./others.sh ./others.sh /home/oracle Sorry, Command execution failed ! hB hB
이처럼 Bash 특수 매개변수를 잘 활용하면 스크립트에서 인자 검증, 프로세스 관리, 오류 처리 등을 훨씬 효율적으로 수행할 수 있습니다. 각 매개변수의 동작 방식을 직접 예제로 실행해 보면서 익혀보시기 바랍니다.