루프 복합 명령 — for · while · until · select

이 글은 GNU Bash 매뉴얼 3.2.5.1 Looping Constructs에서 다루는 반복 구문을, 처음 배우는 분도 따라올 수 있게 쉬운 말로 풀어 정리합니다. “같은 일을 목록만큼 반복”하거나 “조건이 만족될 때까지 반복”하는 방법과, 반복을 중간에 빠져나오는 break / continue를 살펴봅니다.

이 글을 읽고 나면

  • for / while / until을 상황에 맞게 골라 쓸 수 있습니다.

  • C 스타일 for ((i=0; i<n; i++))로 숫자 반복을 작성할 수 있습니다.

  • breakcontinue의 차이를 정확히 구분합니다.

  • 무한 루프와 “공백에서 쪼개지는” 반복 사고를 피할 수 있습니다.

어떤 루프를 골라야 할까

반복문은 종류가 많아 보이지만, 고르는 기준은 “​무엇을 반복할지” 하나입니다.

반복할 대상

알맞은 구문

한 줄 설명

정해진 ​목록 (파일들, 이름들)

for

항목 개수만큼 반복

​조건이 참인 동안

while

언제 끝날지 미리 모를 때

​조건이 참이 될 때까지

until

while의 반대 표현

​숫자 카운터 (0부터 N까지)

for ((…))

C 언어와 비슷한 형태

사용자에게 ​메뉴 선택

select

번호를 붙인 메뉴 출력

Text

목록이 있다 ─────────▶ for 조건으로 돌린다 ──┬──▶ while (참인 동안 계속) └──▶ until (참이 될 때까지) 숫자를 센다 ─────────▶ for ((...)) 사람에게 고르게 한다 ─▶ select

for — 목록의 항목마다 한 번씩

가장 많이 쓰는 형태입니다. 목록을 앞에서부터 하나씩 꺼내 변수에 담고, 그 상태로 do ~ done 사이를 실행합니다.

Bash

for fruit in apple banana cherry; do echo "fruit=$fruit" done

동작을 그림으로 보면 이렇습니다.

Text

목록: apple banana cherry │ │ │ ▼ ▼ ▼ fruit= fruit= fruit= ← 매 회차마다 값이 바뀜 apple banana cherry │ │ │ └── do ~ done 실행 ──┘

항목에 공백이 있을 때

이전 글에서 본 “공백에서 단어가 쪼개지는” 문제가 여기서도 나옵니다. 파일 이름에 공백이 있으면, 한 항목이 두 개로 쪼개질 수 있습니다.

Bash

files=("report final.txt" "notes.md") # 배열로 목록을 만들고 for f in "${files[@]}"; do # 따옴표로 감싸 항목별로 꺼냄 echo "file=[$f]" done

목록을 생략하면

in ...을 아예 쓰지 않으면, 스크립트가 받은 ​인자들 을 반복합니다.

Bash

for arg; do # 'for arg in "$@"' 와 같은 뜻 echo "arg=$arg" done

while — 조건이 참인 동안 계속

몇 번 반복할지 미리 알 수 없을 때 씁니다. 조건을 검사해서 ​성공(참)이면 본문을 실행하고, 다시 조건으로 돌아갑니다.

Bash

count=1 while [ "$count" -le 3 ]; do echo "count=$count" count=$((count + 1)) # 이 줄이 없으면 영원히 반복됩니다 done

​참고: -le, -gt 등 조건 연산자 모음
셸에서 숫자 비교 연산자는 아래와 같이 많이 쓰입니다.

연산자

의미

예시

-eq

equal (같다)

[ "$a" -eq "$b" ]

-ne

not equal (다르다)

[ "$a" -ne "$b" ]

-lt

less than (미만)

[ "$a" -lt "$b" ]

-le

less or equal (이하)

[ "$a" -le "$b" ]

-gt

greater than (초과)

[ "$a" -gt "$b" ]

-ge

greater or equal (이상)

[ "$a" -ge "$b" ]

위 예제의 -le는 "less than or equal to"(이하), 즉 "$count가 3 이하일 때" 반복한다는 뜻이에요.

Text

┌─────────────┐ ▼ │ 조건 검사 ──참──▶ 본문 실행 ──┘ │ 거짓 ▼ 종료

줄 단위로 읽기 (자주 쓰는 형태)

while은 “읽을 것이 남아 있는 동안” 반복할 때 특히 유용합니다.

Bash

printf 'line one\nline two\n' | while IFS= read -r line; do echo "read=[$line]" done
  • IFS= — 줄 앞뒤 공백을 없애지 않고 그대로 둡니다.

  • -r — 백슬래시(\)를 특수 문자로 해석하지 않습니다.

두 가지를 함께 쓰는 것이 안전한 관용구입니다.

until — 조건이 참이 될 때까지

while과 검사 방향만 반대입니다. 조건이 ​실패(거짓)인 동안 반복하고, 참이 되는 순간 멈춥니다.

Bash

n=1 until [ "$n" -gt 3 ]; do # n이 3보다 커지면 종료 echo "n=$n" n=$((n + 1)) done

구문

반복 조건

while 조건

조건이 ​참인 동안 계속

until 조건

조건이 ​거짓인 동안 계속 (참이 되면 종료)

같은 일을 둘 다로 쓸 수 있지만, “~할 때까지 기다린다”는 뜻이면 until이 문장으로 더 자연스럽게 읽힙니다. 예를 들어 “서버가 응답할 때까지 재시도” 같은 상황입니다.

C 스타일 for — 숫자 반복에 편리

숫자를 세는 반복이라면 C 언어와 비슷한 형태가 읽기 좋습니다.

Bash

for ((i = 0; i < 3; i++)); do echo "i=$i" done

괄호 두 겹 안은 세 부분으로 나뉩니다.

위치

역할

첫 번째

시작할 때 한 번 실행

i = 0

두 번째

매 회차 전에 검사

i < 3

세 번째

매 회차 끝에 실행

i++

이 안에서는 $를 붙이지 않아도 변수를 쓸 수 있습니다. 숫자 계산 전용 구역이기 때문입니다.

select — 번호 메뉴 만들기

사용자에게 목록을 보여 주고 번호로 고르게 할 때 씁니다. 형태는 for와 거의 같습니다.

Bash

select fname in a.txt b.txt; do echo "you picked $fname (번호: $REPLY)" break # 고르면 한 번만 처리하고 종료 done
  • 화면에 번호가 붙은 목록이 나오고, 입력 프롬프트가 뜹니다.

  • 고른 값은 변수(fname)에, 입력한 번호는 REPLY에 담깁니다.

  • break가 없으면 계속 다시 묻습니다.

breakcontinue — 반복 흐름 바꾸기

명령

하는 일

continue

이번 회차의 ​남은 부분만 건너뛰고 다음 회차로

break

반복문 ​자체를 즉시 종료

Bash

for num in 1 2 3 4 5; do if [ "$num" -eq 2 ]; then continue # 2는 건너뜀 → 아래 echo 실행 안 함 fi if [ "$num" -eq 4 ]; then break # 4에서 반복 종료 → 5는 아예 안 봄 fi echo "num=$num" done # 출력: num=1, num=3

중첩된 반복문에서는 숫자를 붙여 몇 겹을 빠져나갈지 정할 수 있습니다. break 2는 바깥 반복문까지 두 겹을 종료합니다.

실행 예제

아래 스크립트는 지금까지 본 반복 구문을 한 화면에서 비교해 보여 줍니다.

Bash

#!/usr/bin/env bash # for / while / until / C 스타일 for / break / continue 를 한 화면에서 비교합니다. set -eu echo "=== 1) for: 목록의 각 항목을 한 번씩 ===" for fruit in apple banana cherry; do # (1) 목록을 하나씩 fruit 에 담아 반복 echo "fruit=$fruit" done echo echo "=== 2) for: 공백이 있는 항목도 안전하게 ===" files=("report final.txt" "notes.md") # (2) 배열로 목록을 만듦 for f in "${files[@]}"; do # (3) "${배열[@]}" → 항목별로 하나씩 echo "file=[$f]" done echo echo "=== 3) while: 조건이 참인 동안 반복 ===" count=1 while [ "$count" -le 3 ]; do # (4) count 가 3 이하인 동안 반복 echo "count=$count" count=$((count + 1)) # (5) 조건을 바꿔야 끝남 (무한 루프 방지) done echo echo "=== 4) until: 조건이 참이 될 때까지 반복 ===" n=1 until [ "$n" -gt 3 ]; do # (6) n 이 3 보다 커질 때까지 반복 echo "n=$n" n=$((n + 1)) done echo echo "=== 5) C 스타일 for: 숫자 카운터에 편리 ===" for ((i = 0; i < 3; i++)); do # (7) 초기값; 조건; 증가 echo "i=$i" done echo echo "=== 6) break / continue ===" for num in 1 2 3 4 5; do if [ "$num" -eq 2 ]; then continue # (8) 이번 회차만 건너뛰고 다음으로 fi if [ "$num" -eq 4 ]; then break # (9) 반복 자체를 즉시 종료 fi echo "num=$num" done echo echo "=== 7) while read: 줄 단위로 읽기 ===" printf 'line one\nline two\n' | while IFS= read -r line; do # (10) 한 줄씩 안전하게 echo "read=[$line]" done echo echo "ok — 반복 구문은 '무엇을 반복할지'에 따라 골라 씁니다."

​주요 라인별 설명
1: 목록의 항목을 하나씩 변수에 담아 반복합니다. 가장 기본 형태입니다.
2–3: 공백이 있는 항목은 배열 + "${배열[@]}" 조합으로 안전하게 꺼냅니다.
4–5: while은 조건이 참인 동안 반복합니다. 5번 줄이 없으면 무한 루프가 됩니다.
6: until은 조건이 참이 되는 순간 멈춥니다. while과 방향이 반대입니다.
7: C 스타일 for는 “시작·조건·증가” 세 부분으로 숫자를 셉니다.
8–9: continue는 이번 회차만 건너뛰고, break는 반복 자체를 끝냅니다.
10: IFS= read -r는 줄 내용을 있는 그대로 읽는 안전한 관용구입니다.

실행하면 대략 이런 결과가 나옵니다.

Text

=== 1) for: 목록의 각 항목을 한 번씩 === fruit=apple fruit=banana fruit=cherry === 2) for: 공백이 있는 항목도 안전하게 === file=[report final.txt] file=[notes.md] === 3) while: 조건이 참인 동안 반복 === count=1 count=2 count=3 === 4) until: 조건이 참이 될 때까지 반복 === n=1 n=2 n=3 === 5) C 스타일 for: 숫자 카운터에 편리 === i=0 i=1 i=2 === 6) break / continue === num=1 num=3 === 7) while read: 줄 단위로 읽기 === read=[line one] read=[line two]

break/continue 부분에서 2는 건너뛰어 출력되지 않고, 4에서 반복이 끝나 5는 아예 나오지 않는다는 점을 확인할 수 있습니다.

헷갈리기 쉬운 부분

  1. ​무한 루프while/until 본문에서 조건에 쓰인 값이 변하지 않으면 영원히 돌아갑니다. 값이 바뀌는 줄이 있는지 먼저 확인하세요.

  2. ​목록이 공백에서 쪼개짐for f in $files처럼 따옴표 없이 쓰면 파일 이름의 공백에서 항목이 갈라집니다. 배열과 "${배열[@]}"를 쓰세요.

  3. whileuntil을 반대로 사용 — “~인 동안”은 while, “~가 될 때까지”는 until입니다. 조건식을 그대로 두고 구문만 바꾸면 동작이 뒤집힙니다.

  4. ​파이프 뒤의 while에서 변수가 안 남음cmd | while ... 형태는 별도 프로세스에서 돌아, 루프 안에서 바꾼 변수가 루프 밖에 남지 않을 수 있습니다. (해결 방법은 이후 글에서 다룹니다.)

  5. selectbreak를 안 넣음 — 계속 다시 묻습니다. 한 번만 고르게 하려면 본문 끝에 break가 필요합니다.

한 줄 요약

​목록이 있으면 for, 조건으로 돌리면 while(참인 동안) 또는 until(참이 될 때까지), 숫자를 세면 for ((…))를 쓰고, 흐름은 continue(이번 회차만 건너뜀)와 break(반복 종료)로 조절합니다.

On this page