iBetter Books
수정

case 문

선택지가 여러 개일 때 if-elif-elif-elif...를 계속 늘어놓으면 코드가 금방 지저분해집니다. 이럴 때 case 문을 쓰면 훨씬 깔끔합니다. 변수 하나의 값에 따라 여러 경우를 처리할 때 case는 최적의 선택입니다.

기본 구문

case $변수 in    패턴1)        # 패턴1에 맞을 때 실행        ;;    패턴2)        # 패턴2에 맞을 때 실행        ;;    *)        # 어느 패턴에도 맞지 않을 때 실행        ;;esac

caseesac로 닫습니다. 각 패턴은 ) 로 끝내고, 패턴 블록의 마지막에는 ;;를 붙입니다. *는 아무 패턴에도 맞지 않는 경우를 처리하는 기본값입니다.

패턴 매칭

|를 사용하면 여러 패턴을 OR로 묶을 수 있습니다.

case $answer in    y|Y|yes|YES)        echo "동의합니다."        ;;    n|N|no|NO)        echo "거부합니다."        ;;    *)        echo "알 수 없는 답변입니다."        ;;esac

글로브 패턴도 사용할 수 있습니다.

case $filename in    *.txt|*.md)        echo "텍스트 파일"        ;;    *.sh)        echo "쉘 스크립트"        ;;    *.py)        echo "파이썬 스크립트"        ;;    *)        echo "기타 파일"        ;;esac

;; vs ;;& vs ;& 차이

세 가지 종결자가 있으며, 동작 방식이 다릅니다.

;; - 일반 종결. 해당 패턴 블록을 실행하고 case 문 전체를 빠져나갑니다. 가장 많이 사용합니다.

;;& - 다음 패턴도 검사합니다. 현재 블록 실행 후 아래 패턴들을 계속 검사해서 맞으면 실행합니다.

;& - 다음 블록을 무조건 실행합니다. 패턴 검사 없이 바로 아래 블록으로 이동합니다. C 언어의 fall-through와 비슷합니다.

value="hello"case $value in    hello)        echo "안녕하세요"        ;;&             # 다음 패턴도 검사    h*)        echo "h로 시작합니다"        ;;    *)        echo "기타"        ;;esac

실행 결과는 다음과 같습니다.

안녕하세요
h로 시작합니다

hello가 첫 패턴에 맞아 실행된 뒤 ;;& 때문에 다음 패턴도 검사합니다. h*도 맞으므로 두 번째 블록도 실행됩니다.

실습 1. 메뉴 선택 스크립트

번호를 입력받아 동작을 선택하는 인터랙티브 메뉴 스크립트입니다.

#!/bin/bash# 새 파일: scripts/menu.shecho "============================="echo "  패키지 관리 메뉴"echo "============================="echo "1) 설치"echo "2) 삭제"echo "3) 업데이트"echo "q) 종료"echo "============================="echo -n "선택: "read choicecase $choice in    1)        echo -n "설치할 패키지 이름: "        read pkg        echo "sudo apt install $pkg 실행 중..."        ;;    2)        echo -n "삭제할 패키지 이름: "        read pkg        echo "sudo apt remove $pkg 실행 중..."        ;;    3)        echo "패키지 목록 갱신 및 업그레이드 실행 중..."        echo "sudo apt update && sudo apt upgrade"        ;;    q|Q)        echo "종료합니다."        exit 0        ;;    *)        echo "잘못된 선택입니다: '$choice'"        exit 1        ;;esacecho "작업 완료."

실행 결과는 다음과 같습니다.

$ bash scripts/menu.sh
=============================
  패키지 관리 메뉴
=============================
1) 설치
2) 삭제
3) 업데이트
q) 종료
=============================
선택: 1
설치할 패키지 이름: curl
sudo apt install curl 실행 중...
작업 완료.

$ bash scripts/menu.sh
선택: q
종료합니다.

실습 2. 파일 확장자별 처리 스크립트

파일 경로를 인자로 받아 확장자에 따라 다르게 처리합니다.

#!/bin/bash# 새 파일: scripts/file_handler.shfile="$1"if [[ -z "$file" ]]; then    echo "사용법: $0 <파일경로>"    exit 1fiif [[ ! -f "$file" ]]; then    echo "오류: 파일이 없습니다 - $file"    exit 1fiext="${file##*.}"case $ext in    txt|md)        echo "텍스트 파일입니다."        echo "줄 수: $(wc -l < "$file")"        echo "--- 내용 미리보기 ---"        head -5 "$file"        ;;    sh)        echo "쉘 스크립트입니다."        echo "실행 권한 확인 중..."        if [[ -x "$file" ]]; then            echo "실행 권한이 있습니다."        else            echo "실행 권한이 없습니다. chmod +x $file 을 실행하세요."        fi        ;;    py)        echo "파이썬 스크립트입니다."        python3 --version 2>/dev/null || echo "python3가 설치되지 않았습니다."        echo "실행: python3 $file"        ;;    gz|tar|zip)        echo "압축 파일입니다."        echo "크기: $(du -sh "$file" | cut -f1)"        ;;    *)        echo "알 수 없는 확장자입니다: .$ext"        echo "파일 타입 확인: $(file "$file")"        ;;esac

실행 결과는 다음과 같습니다.

$ bash scripts/file_handler.sh /etc/hostname
텍스트 파일입니다.
줄 수: 1
--- 내용 미리보기 ---
ubuntu

$ bash scripts/file_handler.sh scripts/menu.sh
쉘 스크립트입니다.
실행 권한 확인 중...
실행 권한이 없습니다. chmod +x scripts/menu.sh 을 실행하세요.

${file##*.}는 파일명에서 마지막 . 이후 문자열, 즉 확장자를 추출하는 매개변수 확장입니다. ##는 가장 긴 접두어를 제거하라는 의미입니다. 이 패턴은 PART 05에서 더 자세히 다룹니다.