Skip to content

11. 테스트와 분기(Testing and Branching)


caseselect는 코드 블럭을 반복해서 수행하지 않기 때문에 기술적으로는 루프가 아니다. 하지만 루프가 하는 것처럼 특정 블럭의 위나 아래에서 주어진 조건에 따라 프로그램 흐름을 조정해 준다.


case는 C/C++의 switch와 동일하다. 조건에 따라 여러 개의 코드 블럭 중 하나로 분기할 수 있게 해주는데, 여러 개의 if/then/else의 간단한 표기법처럼 동작하기 때문에 메뉴같은 것을 만들 때 적당하다.


다음은 case의 기본 문법이다.


case "$variable" in
"$condition1")
    command
    ;;
"$condition2")
    command
    ;;
*)
    command
    ;;
esac
#!/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

case $(arch) in
"i386") echo "80386 기반의 머신" ;;
"i486") echo "80486 기반의 머신" ;;
"i586") echo "Pentium 기반의 머신" ;;
"i686") echo "Pentium2+ 기반의 머신" ;;
*)
    echo -n "다른 형태의 머신: "
    echo $(arch)
    ;;
esac
# 다른 형태의 머신: arm64

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 variable [in list]; do
    command
    break
done
예제) 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

References