11. 테스트와 분기(Testing and Branching)
case
와 select
는 코드 블럭을 반복해서 수행하지 않기 때문에 기술적으로는 루프가 아니다. 하지만 루프가 하는 것처럼 특정 블럭의 위나 아래에서 주어진 조건에 따라 프로그램 흐름을 조정해 준다.
case
는 C/C++의 switch
와 동일하다. 조건에 따라 여러 개의 코드 블럭 중 하나로 분기할 수 있게 해주는데, 여러 개의 if
/then
/else
의 간단한 표기법처럼 동작하기 때문에 메뉴같은 것을 만들 때 적당하다.
다음은 case
의 기본 문법이다.
#!/bin/bash
while True; do
echo "아무키나 누른 다음 리턴을 치세요."
read Keypress
case "$Keypress" in
"X")
echo "종료합니다."
exit 0
;;
[a-z])
echo "소문자"
;;
[A-Z])
echo "대문자"
;;
[0-9])
echo "숫자"
;;
*)
echo "구두점이나, 공백문자 등"
;;
esac
done
# 아무키나 누른 다음 리턴을 치세요.
# a (입력)
# 소문자
# 아무키나 누른 다음 리턴을 치세요.
# A (입력)
# 대문자
# 아무키나 누른 다음 리턴을 치세요.
# 1 (입력)
# 숫자
# 아무키나 누른 다음 리턴을 치세요.
# X (입력)
# 종료합니다.
exit 0
#!/bin/bash
echo "다음 중 한 명을 고르세요:"
echo "[E]vans, Roland"
echo "[J]ones, Mildred"
# 다음 중 한 명을 고르세요:
# [E]vans, Roland
# [J]ones, Mildred
read person
# 변수 쿼우트
case "$person" in
"E" | "e")
# 대소문자 모두 인식.
echo "Roland Evans"
echo "4321 Floppy Dr."
echo "Hardscrabble, CO 80753"
echo "(303) 734-9874"
echo "(303) 734-9892 fax"
echo "revans@zzy.net"
echo "Business partner & old friend"
;;
"J" | "j")
echo "Mildred Jones"
echo "249 E. 7th St., Apt. 19"
echo "New York, NY 10009"
echo "(212) 533-2814"
echo "(212) 533-9972 fax"
echo "milliej@loisaida.com"
echo "Girlfriend"
echo "Birthday: Feb. 11"
;;
*)
echo "아직 등록이 안 돼 있습니다."
;;
esac
# e (입력)
# Roland Evans
# 4321 Floppy Dr.
# Hardscrabble, CO 80753
# (303) 734-9874
# (303) 734-9892 fax
# revans@zzy.net
# Business partner & old friend
exit 0
#!/bin/bash
match_string() {
MATCH=0
NOMATCH=90
PARAMS=2
BAD_PARAMS=91
[ "$#" -eq $PARAMS ] || return $BAD_PARAMS
# if [ "$#" -ne $PARAMS ]; then
# return $BAD_PARAMS
# fi
case "$1" in
"$2") return $MATCH ;;
*) return $NOMATCH ;;
esac
}
a="one"
b="two"
c="three"
d="two"
match_string $a
echo $?
# 91
match_string $a $b
echo $?
# 90
match_string $b $d
echo $?
# 0
exit 0
#!/bin/bash
SUCCESS=0
FAILURE=-1
isalpha() {
if [ -z "$1" ]; then
return $FAILURE
fi
case "$1" in
[a-zA-Z]*) return $SUCCESS ;;
*) return $FAILURE ;;
esac
}
isalpha2() {
[ "$#" -eq 1 ] || return $FAILURE
# if [ "$#" -ne 1 ]; then
# return $FAILURE
# fi
case "$1" in
*[!a-zA-Z]* | "") return $FAILURE ;;
*) return $SUCCESS ;;
esac
}
check_var() {
if isalpha "$@"; then
echo "$* = 알파벳"
else
echo "$* = 알파벳 아님"
fi
}
a="23skidoo"
b="H3ll0"
c="-What?"
d=$(echo $b)
check_var $a
# 23skidoo = 알파벳 아님
check_var $b
# H3ll0 = 알파벳
check_var $c
# -What? = 알파벳 아님
check_var $d
# H3ll0 = 알파벳
check_var
# = 알파벳 아님
exit 0
select
는 메뉴를 만들 때 사용할 수 있다.
다음은 select
의 기본 문법이다.
예제) select로 메뉴 만들기
#!/bin/bash
# PS3 프롬프트
PS3="제일 좋아하는 채소를 고르세요: "
select vegetable in "콩" "당근" "감자" "양파" "순무"; do
echo "제일 좋아하는 채소가 ${vegetable} 이네요."
break
done
# 1) 콩
# 2) 당근
# 3) 감자
# 4) 양파
# 5) 순무
# 제일 좋아하는 채소를 고르세요: 1 (입력)
# 제일 좋아하는 채소가 콩 이네요.
exit 0
in list
없이 사용하면 select
는 스크립트나 select
를 포함하고 있는 함수로 넘어온 명령어줄 인자($@
)를 사용한다.
예제) 함수에서 select를 사용하여 메뉴 만들기
#!/bin/bash
# PS3 프롬프트
PS3="제일 좋아하는 채소를 고르세요: "
choice_of() {
# select에 [in list]가 빠져있기 때문에, 함수로 넘어온 인자를 사용함
select vegetable; do
echo "제일 좋아하는 채소가 ${vegetable} 이네요."
break
done
}
choice_of "콩" "쌀" "당근" "무" "토마토" "시금치"
# 1) 콩 3) 당근 5) 토마토
# 2) 쌀 4) 무 6) 시금치
# 제일 좋아하는 채소를 고르세요: 1 (입력)
# 제일 좋아하는 채소가 콩 이네요.
exit 0