본문 바로가기
C.W.K.
Stream
Lesson 03 of 12 · published

조건문: if/elif/else와 [[ ]]

~12 min · if, test, comparison

Level 0창 구경꾼
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

모양

if [[ 조건 ]]; then
  # ...
elif [[ 다른 조건 ]]; then
  # ...
else
  # ...
fi

if는 참·거짓 값을 따로 받지 않고 명령의 종료 상태를 봐. 0이면 then, 0이 아니면 else로 가. [[ ... ]]는 bash와 zsh가 제공하는 조건 구문이라 패턴과 정규식 같은 기능이 풍부하지만, POSIX sh에서는 쓸 수 없어.

문자열 테스트

  • [[ -z "$x" ]]: 비어 있음.
  • [[ -n "$x" ]]: 비어 있지 않음.
  • [[ "$a" == "$b" ]]: 같음.
  • [[ "$a" != "$b" ]]: 다름.
  • [[ "$x" == prefix* ]]: 글로브 매치 ([[ ]] 안에서만).
  • [[ "$x" =~ ^[0-9]+$ ]]: 정규식 매치 (bash/zsh).

숫자 테스트

  • [[ $a -eq $b ]]: 같음 (eq, ne, lt, le, gt, ge).
  • (( a == b )): 산술 맥락 (수학에 더 깔끔).

파일 테스트

  • [[ -f path ]]: 일반 파일 존재.
  • [[ -d path ]]: 디렉터리.
  • [[ -e path ]]: 존재 (타입 무관).
  • [[ -r path ]], -w, -x: 읽기 / 쓰기 / 실행.
  • [[ -s path ]]: 존재 + 비어 있지 않음.

논리 연산자를 조합해

if [[ -f config.yaml && -r config.yaml ]]; then ...
if [[ -z "$NAME" || -z "$EMAIL" ]]; then ...

[[ ]] 안에선 &&, || 사용. 밖에선 명령 자체를 체이닝.

조건식보다 종료 상태가 먼저야

if grep -q pattern file; then처럼 명령을 그대로 조건으로 쓰면 굳이 $?를 중간 변수에 담지 않아도 돼. 다만 ‘찾지 못함’과 ‘파일을 읽지 못함’이 서로 다른 종료 상태를 쓰는 명령도 있어. 중요한 분기라면 매뉴얼 페이지에서 상태 값을 확인하고, 모든 0 아닌 값을 같은 실패로 뭉개지 마.

패턴과 문자열을 구분해

[[ $x == prefix* ]]에서 오른쪽의 별표는 패턴이지만 [[ $x == "$literal" ]]처럼 인용하면 글자 그대로 비교해. 같은 기호가 문맥에 따라 역할을 바꾸므로, 비교하려는 것이 값인지 패턴인지 먼저 정하는 습관이 필요해.

Code

실전 조건문·bash
#!/usr/bin/env bash
set -euo pipefail
config=~/.config/myapp/config.yaml
if [[ -f "$config" && -r "$config" ]]; then
  echo "using $config"
elif [[ -n "${MYAPP_FALLBACK:-}" ]]; then
  echo "using fallback $MYAPP_FALLBACK"
else
  echo 'no config' >&2
  exit 1
fi

External links

Exercise

첫 인자가 일반 파일인지 [[ -f $1 ]]로 검사하는 스크립트를 만들고 파일, 디렉터리와 없는 경로를 각각 넘겨 봐. [[ -s $1 ]] 조건을 더해 비어 있지 않은 파일만 통과하게 한 뒤 각 실패가 분명한 종료 상태를 내는지도 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.