변수 하나를 여러 값과 견주어 분기할 때 if 를 여러 번 잇는 대신 case 를 쓴다. 비교는 문자열 동등이 아니라 글로브 패턴 매칭이라 * · ? · [...] 이 그대로 동작한다.
#!/bin/bash
ACTION="$1"
case "$ACTION" in
start)
echo "시작"
;;
stop)
echo "정지"
;;
restart)
echo "재시작"
;;
*)
echo "usage: $0 {start|stop|restart}" >&2
exit 1
;;
esac
각 분기는 패턴) 으로 열고 ;; 으로 닫는다. *) 는 어떤 패턴도 맞지 않을 때 걸리는 기본 분기이며 마지막에 둔다. 패턴은 위에서부터 차례로 검사해 처음 맞는 하나만 실행한다.
변수는 "$VAR" 로 감싼다. 값이 비었을 때 case in 이 되어 문법 오류가 나는 것을 막아 준다.
case "$FILE" in
*.tar.gz|*.tgz) tar xzf "$FILE" ;;
*.tar.bz2) tar xjf "$FILE" ;;
*.zip) unzip "$FILE" ;;
*) echo "모르는 형식: $FILE" >&2 ;;
esac
| 패턴 | 뜻 |
|---|---|
a\|b |
a 또는 b |
* |
임의의 문자열 (빈 문자열 포함) |
? |
임의의 한 글자 |
[0-9] |
범위 안의 한 글자 |
[!0-9] |
범위 밖의 한 글자 |
대소문자를 가리지 않으려면 값을 미리 접는다. ${VAR,,} 은 bash 4 이상에서만 동작하므로 sh 로 실행할 스크립트에서는 tr 을 쓴다.
case "$(printf '%s' "$ANSWER" | tr 'A-Z' 'a-z')" in
y|yes) ;;
*) exit 1 ;;
esac
;; 외에 두 가지가 더 있다. 둘 다 bash 전용이고 POSIX sh 에는 없다.
| 종결자 | 동작 |
|---|---|
;; |
분기를 끝내고 esac 뒤로 나간다 |
;& |
다음 분기의 본문을 패턴 검사 없이 이어서 실행한다 |
;;& |
다음 분기부터 패턴 검사를 계속한다 |