if 문이 “예/아니오”라는 논리적 판단에 강하다면, case 문은 “이 값은 어디에 해당하나?”라는 패턴 매칭에 최적화되어 있습니다.
코드의 가독성을 높여주는 case 문의 모든 것을 알아봅니다.
기본 구조
case 문은 변수의 값을 여러 패턴과 비교하며, 처음으로 일치하는 블록을 실행합니다.
case "$변수" in
패턴1)
명령어
;; # 블록 종료 (C의 break와 유사)
패턴2|패턴3)
명령어 # | 로 OR 조건 표현 가능
;;
*)
명령어 # 일치하는 패턴이 없을 때 (else 역할)
;;
esac # case를 거꾸로 쓴 것
활용 가능한 패턴 종류
POSIX 표준에서 지원하는 패턴들입니다. 정규표현식과는 조금 다르니 주의하세요!
*: 모든 문자열과 일치 (Default 처리용)?: 임의의 문자 딱 1개와 일치[abc]: a, b, c 중 하나와 일치[a-z]: 소문자 a부터 z 사이의 문자 하나와 일치pat1|pat2: 패턴1 또는 패턴2 중 하나와 일치 (OR 조건)
예제
① 스크립트 인자(Argument) 처리 : 서비스 관리 스크립트(start, stop 등)를 만들 때 가장 많이 쓰이는 방식입니다.
#!/bin/sh
ACTION="$1"
case "$ACTION" in
start)
printf "서비스를 시작합니다...\n"
;;
stop)
printf "서비스를 중지합니다...\n"
;;
restart|reload)
printf "재시작/설정 로드를 수행합니다...\n"
;;
status)
printf "현재 상태를 확인합니다...\n"
;;
*)
printf "사용법: %s {start|stop|restart|status}\n" "$0"
exit 1
;;
esac
② 파일 확장자별 분기 처리 : ${FILE##*.}와 조합하면 매우 강력해집니다.
#!/bin/sh
FILE="backup.tar.gz"
EXT="${FILE##*.}"
case "$EXT" in
gz|tgz)
printf "Gzip 압축 파일입니다. 해제 명령: tar xzf %s\n" "$FILE"
;;
zip)
printf "Zip 파일입니다. 해제 명령: unzip %s\n" "$FILE"
;;
log)
printf "로그 파일입니다. 실시간 모니터링을 시작합니다.\n"
;;
*)
printf "지원하지 않는 파일 형식입니다: %s\n" "$EXT"
;;
esac
사용자 입력(y/n) 대소문자 무시하기
사용자로부터 yes, Yes, YES 등을 한 번에 입력받고 싶을 때 대괄호([]) 패턴이 유용합니다.
#!/bin/sh
printf "계속 진행하시겠습니까? [y/n]: "
read ANSWER
case "$ANSWER" in
[yY]|[yY][eE][sS])
printf "진행을 결정하셨습니다.\n"
;;
[nN]|[nN][oO])
printf "작업을 취소합니다.\n"
exit 0
;;
*)
printf "잘못된 입력입니다. y 또는 n을 입력해 주세요.\n"
exit 1
;;
esac
고급: Bash 전용 기능 주의사항
Bash 4.0 이상에서는 ; 대신 ;& (fall-through)나 ;;& 등을 사용할 수 있지만, 이는 POSIX 표준이 아닙니다.
; &: 다음 패턴의 일치 여부와 상관없이 무조건 다음 블록을 실행합니다.;; &: 다음 패턴들을 계속 검사하여 일치하는 것이 있다면 또 실행합니다.
POSIX 팁: 이식성이 중요한 스크립트에서는 오직 ;;만 사용하세요. ; 하나만 쓰거나 다른 기호를 섞으면 구형 쉘에서 에러가 납니다.
if vs case: 언제 무엇을 쓸까?
if문이 유리할 때: 숫자 크기 비교(-gt,-lt), 복잡한 논리 조합(&&,||), 파일 존재 여부 확인 등.case문이 유리할 때: 하나의 변수 값이 특정 문자열 패턴 중 무엇인지 분류할 때 (3개 이상의 분기라면case를 강력 추천).
case 문을 사용하면 스크립트가 훨씬 읽기 쉬워지고 구조가 명확해집니다.
특히 인자 처리나 사용자 응답 처리에서 case를 활용해 보세요. 여러분의 코드가 한층 더 전문가답게 보일 것입니다!


