Skip to content

8. 루프(Loop)


루프란 루프 제어 조건이 참인 동안에 여러 명령어들을 반복적으로 수행하는 코드 블럭이다.


다음은 for 루프의 기본 문법이다.


for arg in [list]; do
    command
done


루프의 각 단계마다 list의 값들이 arg에 들어간다.


#!/bin/bash

for arg in "$var1" "$var2" "$var3" ... "$varN"
# 루프 1단계, $arg = $var1
# 루프 2단계, $arg = $var2
# 루프 3단계, $arg = $var3
# ...
# 루프 N단계, $arg = $varN

# [list]의 인자들은 쿼우팅을 해서 낱말 분리를 방지함

exit 0
#!/bin/bash

for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto; do
    echo $planet
done
# Mercury
# Venus
# Earth
# Mars
# Jupiter
# Saturn
# Uranus
# Neptune
# Pluto

# 따옴표로 묶인 전체 목록은 한 개의 변수를 만들어 냄
for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"; do
    echo $planet
done
# Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto

exit 0
#!/bin/bash

for planet in "Mercury 36" "Venus 67" "Earth 93" "Mars 142" "Jupiter 483"; do
    # "planet" 변수를 파싱해서 위치 매개변수로 세팅
    # "--"를 사용하면 널이거나 대시 문자로 시작하는 등의 상황을 처리해 줌
    set -- $planet

    # 원래의 위치 매개변수는 덮어써지기 때문에 따로 저장해야 함
    # original_params=("$@")

    echo "${1} -> 해까지의 거리 ${2},000,000 마일"
done
# Mercury -> 해까지의 거리 36,000,000 마일
# Venus -> 해까지의 거리 67,000,000 마일
# Earth -> 해까지의 거리 93,000,000 마일
# Mars -> 해까지의 거리 142,000,000 마일
# Jupiter -> 해까지의 거리 483,000,000 마일

exit 0
#!/bin/bash

FILES="/usr/sbin/privatepw
/sbin/ypbind
/Users/SAEMC/test"

for file in $FILES; do
    # "!"과 "-e"라는 복합 명령이므로 "[[]]" 사용
    # 단순 내장 명령이라면 "[]" 사용
    if [[ ! -e "$file" ]]; then
        echo "${file} 은 존재하지 않는 파일입니다."
        # 다음 파일 확인
        continue
    fi

    ls -l $file | awk '{ print $9 " -> 파일 크기: " $5 }'
    # 파일에 대한 정보
    # whatis $(basename $file)
done
# /usr/sbin/privatepw 은 존재하지 않는 파일입니다.
# /sbin/ypbind 은 존재하지 않는 파일입니다.
# /Users/SAEMC/test -> 파일 크기: 0

exit 0
#!/bin/bash

for file in *; do
    # $PWD의 모든 파일을 나열
    ls -l "$file"
done
# -rw-r--r--  1 SAEMC  staff  0 Mar 10 21:58 ajump.txt
# -rw-r--r--  1 SAEMC  staff  0 Mar 10 21:58 jump.txt
# -rw-r--r--  1 SAEMC  staff  120 Mar 10 21:58 test.sh
# -rw-r--r--  1 SAEMC  staff  0 Mar 10 21:58 xjump.txt

for file in [jx]*; do
    # $PWD에서 "j"나 "x"로 시작하는 모든 파일을 지움
    rm -f ${file}
    echo "\"${file}\"이 지워졌습니다."
done
# "jump.txt"이 지워졌습니다.
# "xjump.txt"이 지워졌습니다.

exit 0


다음과 같이 for 루프에서 in [list]를 사용하지 않으면, 명령어줄에서 넘어 온 인자인 $@에 대해서 동작한다.


예제) in [list]가 빠진 for 루프
#!/bin/bash

# 스크립트 실행 시 1 2 3 인자 입력

for a; do
    echo "$a"
done
# 1
# 2
# 3

exit 0


다음과 같이 for 루프의 [list]에 명령어 치환을 사용할 수 있다.


#!/bin/bash

NUMBERS="9 7 3 8 37.53"

for number in $(echo $NUMBERS); do
    echo "$number"
done
# 9
# 7
# 3
# 8
# 37.53

for number in $NUMBERS; do
    echo "$number"
done
# 9
# 7
# 3
# 8
# 37.53

exit 0
#!/bin/bash

E_BADARGS=65
E_NOFILE=66

if [ "$#" -ne 2 ]; then
    echo "사용법: $(basename $0) string filename"
    exit $E_BADARGS
fi

if [[ ! -f "$2" ]]; then
    echo "\"$2\" 은 존재하지 않는 파일입니다."
    exit $E_NOFILE
fi

# "strings" 명령어는 이진 파일에 들어 있는 문자열들을 보여주고
# 그 출력을 "grep"에 파이프로 걸어 원하는 문자열을 찾아냄
for word in $(strings "$2" | grep "$1"); do
    echo $word
done

exit 0
#!/bin/bash

ARGS=1

if [ $# -ne "$ARGS" ]; then
    directory=$(pwd)
else
    directory=$1
fi

echo "\"$directory\" 디렉터리의 심볼릭 링크들"

for file in "$(find $directory -type 1)"; do
    echo "$file"
done | sort

exit 0
#!/bin/bash

ARGS=1
OUTFILE=symlinks.list

if [ $# -ne "$ARGS" ]; then
    directory=$(pwd)
else
    directory=$1
fi

echo "\"$directory\" 디렉터리의 심볼릭 링크들"

for file in "$(find $directory -type 1)"; do
    echo "$file"
done | sort >"$OUTFILE"

exit 0
#!/bin/bash

# 표준 문법
for a in 1 2 3; do
    echo "$a"
done
# 1
# 2
# 3

# C 형태의 문법
LIMIT=3

for ((a = 1; a <= LIMIT; a++)); do
    echo "$a"
done
# 1
# 2
# 3

# 변수 추가
for ((a = 1, b = 1; a <= LIMIT; a++, b++)); do
    # echo "$(($a - $b))"
    let "result = $a - $b"
    echo "$result"
done
# 0
# 0
# 0

exit 0


while 루프는 루프 최상단에서 특정 조건을 확인하면서 그 조건이 참일 동안 루프를 계속 돌도록 해준다.


다음은 while 루프의 기본 문법이다.


while [condition]; do
    command
done
#!/bin/bash

var0=0
LIMIT=5

while [ "$var0" -lt "$LIMIT" ]; do
    echo "$var0"
    var0=$(expr $var0 + 1)
    # $(expr a) == $((a))
    # var0=$(($var0 + 1))
done
# 0
# 1
# 2
# 3
# 4

exit 0
#!/bin/bash

var0=0
LIMIT=5

while [ "$var0" != "$LIMIT" ]; do
    echo "변수값을 넣으세요 #1 (끝내려면 end) "
    read var1
    echo "변수 #1 = ${var1}"
done
# 변수값을 넣으세요 #1 (끝내려면 end)
# 2 (입력)
# 변수 #1 = 2

exit 0
#!/bin/bash

var1=unset
previous=$var1

while
    previous=$var1
    echo "이전 변수 = $previous"
    # 바로 전의 "var1"이 무엇이었는지 계속 확인
    [ "$var1" != end ]
do
    echo "변수값을 넣으세요 #1 (끝내려면 end) "
    read var1
    echo "변수 #1 = ${var1}"
done
# 이전 변수 = unset
# 변수값을 넣으세요 #1 (끝내려면 end)
# 1 (입력)
# 변수 #1 = 1
# 이전 변수 = 1
# 변수값을 넣으세요 #1 (끝내려면 end)
# 2 (입력)
# 변수 #1 = 2
# 이전 변수 = 2
# 변수값을 넣으세요 #1 (끝내려면 end)
# end (입력)
# 변수 #1 = end
# 이전 변수 = end

exit 0
#!/bin/bash

# 표준 문법
LIMIT=5
a=1

while [ "$a" -le $LIMIT ]; do
    echo "$a"
    let "a += 1"
done
# 1
# 2
# 3
# 4
# 5

# C 형태의 문법
# a=1
((a = 1))

while ((a <= LIMIT)); do
    echo "$a"
    ((a += 1))
done
# 1
# 2
# 3
# 4
# 5

exit 0


until 루프는 루프 최상단에서 특정 조건을 확인하면서 그 조건이 거짓일 동안 루프를 계속 돌도록 해준다. 이는 while 루프와 동작하는 것이 반대이다.


다음은 until 루프의 기본 문법이다.


until [condition-is-true]; do
    command
done
예제) until 루프
#!/bin/bash

until [ "$var1" = end ]; do
    echo "변수 값을 넣으세요 #1 (끝내려면 end) "
    read var1
    echo "변수 #1 = ${var1}"
done
# 변수 값을 넣으세요 #1 (끝내려면 end)
# 1 (입력)
# 변수 #1 = 1
# 변수 값을 넣으세요 #1 (끝내려면 end)
# 2 (입력)
# 변수 #1 = 2
# 변수 값을 넣으세요 #1 (끝내려면 end)
# end (입력)
# 변수 #1 = end

exit 0

References