Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

실전 예제 셸 스크립트 4가지로 배우는 Bash 특수 매개변수 완벽 정리

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 특수 매개변수를 잘 활용하면 스크립트에서 인자 검증, 프로세스 관리, 오류 처리 등을 훨씬 효율적으로 수행할 수 있습니다. 각 매개변수의 동작 방식을 직접 예제로 실행해 보면서 익혀보시기 바랍니다.