[쉘 스크립트] 쉘 스크립트 기초 - 반복문 (3)
카테고리: Linux
태그: Linux
🎯구조적 명령 (2) - 반복문
for문
# 형식 1:
for var in list
do
commands1
commands2
done
# 형식 2:
for var in list; do commands1; commands2; done
list매개변수에는 반복에 사용할 값의 집합을 제공한다.var변수는list중 현재의 값을 포함한다.list안의 모든 항목을 사용할 때까지 반복된다.do와done사이에 있는 명령들은 하나 또는 그 이상의 bash 표준 쉘 명령들이다.
명령 치환으로 목록 만들기
list매개변수를 만드는 방법으로 또 다른 명령의 출력을 사용할 수 있다.- 사용자는 출력을 만들어내는 어떤 명령이든 이를 실행하고, 그 출력을 목록에 치환한다.
- 다음은
cat명령의 출력을 목록으로 만드는 예이다.
$ cat states
Alabama
Alaska
Arizona
Arkansas
$ cat forsubstitution.sh
#!/bin/bash
for state in $(cat states)
do
echo "Visit beautiful $state"
done
$ ./forsubstitution.sh
Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Note:
기본적으로 for 명령은 각각의 목록을 white space(들여쓰기, 공백, 줄바꿈)로 구분한다. 필드 구분자를 변경하는 방법은 필드 구분자 변경하기 참고하라.
필드 구분자 변경하기
IFS라고 하는 특수한 환경 변수는 bash 쉘이 필드 구분자로 사용하는 문자의 목록을 정의한다.- bash 쉘은 기본적으로 (들여쓰기, 공백, 줄바꿈)을 필드 구분을 위한 기호로 간주한다.
- IFS 환경 변수 값을 바꿈으로써 일시적으로 필드 구분자를 변경할 수 있다.
- IFS 환경 변수 값으로 어떠한 문자도 사용 가능하다.
- 다음은 필드 구분자를 정의한느 방법을 나타낸다.
# 필드 구분자로 줄바꿈 문자를 사용한다. (줄바꿈 문자를 IFS 문자로 사용하는 경우에는 형식에 주의하라.)
IFS=$'\n'
# 필드 구분자로 줄바꿈, 콜론(:), 세미콜론(;) 문자를 사용한다.
IFS=$'\n':;
# 긴 스크립트를 다룰 댸에는 기존 IFS 문자를 백업 후 변경하는 것이 좋다.
IFS.OLD=$IFS
IFS=<The new IFS value>
IFS=$IFS.OLD
와일드카드를 써서 목록 만들기
- 와일드카드(*) 문자를 이용하면 디렉토리 안의 파일을 차례차례 목록으로 만들 수 있다.
- 와일드카드 문자를 사용하면 쉘은 강제로 파일 글로빙을 실행한다.
- 파일 글로빙은 지정된 와일드카드 문자와 일치하는 파일 이름 또는 경로 이름을 만들어 내는 과정이다.
- 다음은 와일드카드 문자를 써서 디렉토리 내의 파일을 목록으로 만드는 방법이다.
$ cat forwildcard.sh
#!/bin/bash
for file in /root/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done
$ ./forwildcard.sh
/root/aws is a directory
/root/awscliv2.zip is a file
/root/bashscript is a directory
/root/cow-test is a directory
C 스타일의 for문
- bash 쉘 또한 C 스타일의 for문과 비슷한 모습의 for문을 지원한다.
- 다음은 C 스타일 for문의 기본 형식이다.
for (( variable assignment; condition; iteration process ))
- 다만, C 스타일의 for문은 표준 bash 쉘의 규칙을 따르지 않는 몇 가지 사항이 있다.
- 변수 값 할당문에 빈칸이 포함되어 있다.
- 조건문에 사용되는 변수 앞에 달러($) 기호가 붙지 않는다.
- 반복 프로세스의 수식에 expr 명령 형식이 사용되지 않는다.
- 다음은 bash 쉘 프로그래밍에서 C 스타일의 for문을 사용하는 예이다.
$ cat cfor.sh
#!/bin/bash
for (( i = 1; i <= 10; i++ ))
do
echo "The next number is $i"
done
$ ./cfor.sh
The next number is 1
The next number is 2
The next number is 3
The next number is 4
The next number is 5
The next number is 6
The next number is 7
The next number is 8
The next number is 9
The next number is 10
while문
while test command
do
commands1
commands2
done
- while문은
test command을 정의하고test command이 종료 상태 0을 되돌려 주는 동안에는 반복된다. - while문은 반복이 시작될 때마다
test command을 실행한다. test command가 0이 아닌 종료 상태를 되돌려 주면 while문은 반복을 중단한다.- 다음은 while 문을 사용하는 예이다.
$ cat while.sh
#!/bin/bash
var=10
while [ $var -gt 0 ]
do
echo $var
((var--))
done
$ ./while.sh
10
9
8
7
6
5
4
3
2
1
until문
until test command
do
commands1
commands2
done
- until문은 while문과는 정반대 방식으로 작동한다.
test command의 종료 상태가 0이 아닌 한 loop 안의 명령을 반복하고 종료 상태 0을 반환하면 반복은 종료된다.
루프 제어
- break문
- continue문
break문
- break문은 진행 중인 루프에서 탈출할 수 있는 방법을 제공한다.
- while과 until 루프를 포함하여 어떤 유형의 루프든 break문으로 탈출할 수 있다.
- 중첩된 루프가 있는 경우 break문은 기본적으로 가장 안쪽에 있는 루프를 종료시킨다.
- 다음은 중첩된 루프에서 가장 안쪽에 있는 루프를 종료시키는 예이다.
$ cat innerloopbreak.sh
#!/bin/bash
for (( a = 1; a <= 3; a++ ))
do
echo "Outer loop: $a"
for (( b = 1; b <= 100; b++ ))
do
if [[ $b -eq 5 ]]
then
break
fi
echo " Inner loop: $b"
done
done
$ ./innerloopbreak.sh
Outer loop: 1
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
Outer loop: 2
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
Outer loop: 3
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
바깥쪽 루프 탈출하기
break n
- break문은 기본적으로 가장 안쪽에 있는 루프에서 탈출하지만 종종 바깥쪽 루프에서 탈출해야 할 때도 있다.
- break문의 매개변수(n)를 이용하여 해결할 수 있다.
- n의 기본값은 1로, 현재의 루프를 뜻한다. n의 값을 2로 설정하면 한 단계 위의 루프를 뜻한다.
- 다음은 바깥쪽 루프를 탈출하는 방법을 보여준다.
$ cat oputerloopbreak.sh
#!/bin/bash
for (( a = 1; a <= 3; a++ ))
do
echo "Outer loop: $a"
for (( b = 1; b <= 100; b++ ))
do
if [[ $b -eq 5 ]]
then
break 2
fi
echo " Inner loop: $b"
done
done
$ ./oputerloopbreak.sh
Outer loop: 1
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
continue문
- loop에서 continue문을 만나면 continue문 이후에 나오는 명령을 실행하지 않고 바로 반복 조건문을 평가한다.
- continue문도 break문과 마찬가지로 매개변수(n)을 통해 어느 수준의 루프를 속개할 것인지를 정할 수 있다.
- 다음은 중첩된 loop에서 continue문을 사용하는 예제이다.
$ cat nestedloopcontinue.sh
#!/bin/bash
for (( a = 1; a <= 5; a++ ))
do
echo "Iteration $a:"
for (( b = 1; b < 3; b++ ))
do
if [[ $a -gt 2 ]] && [[ $a -lt 4 ]]
then
continue 2
fi
echo "The result of $a * $b is $[$a*$b]"
done
done
$ ./nestedloopcontinue.sh
Iteration 1:
The result of 1 * 1 is 1
The result of 1 * 2 is 2
Iteration 2:
The result of 2 * 1 is 2
The result of 2 * 2 is 4
Iteration 3:
Iteration 4:
The result of 4 * 1 is 4
The result of 4 * 2 is 8
Iteration 5:
The result of 5 * 1 is 5
The result of 5 * 2 is 10
루프의 출력 처리하기
- 쉘 스크립트에서 루프의 출력을 파이프 또는 리다이렉트할 수 있다.
- done 끝에 이러한 처리 명령을 덧붙이면 된다.
- 다음은 루프의 출력을 파이프와 리다이렉트 처리하는 방법을 보여준다.
# TODO 1. 파이프
$ cat pipeloop.sh
#!/bin/bash
for state in "North Dakota" Conneticut Illinois Alabama Tenessee
do
echo "$state is the next place to go"
done | sort
echo "This completes our travels"
$ ./pipeloop.sh
Alabama is the next place to go
Conneticut is the next place to go
Illinois is the next place to go
North Dakota is the next place to go
Tenessee is the next place to go
This completes our travels
# TODO 2. 리다이렉트
$ cat redirectloop.sh
#!/bin/bash
for (( a = 1; a < 10; a++ ))
do
echo "The number is $a"
done > number.txt
$ ./redirectloop.sh
$ cat number.txt
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
The number is 6
The number is 7
The number is 8
The number is 9
📖출처
리처드 블룸, 크리스틴 브레스, ⌜리눅스 커맨드라인 쉘 스크립트 바이블⌟, 스포트라잇북(2016)
👍 개인 공부 기록용 블로그입니다. 오류나 조언이 있으시면 언제든지 댓글 혹은 메일로 남겨주시면 감사하겠습니다! 😄
댓글남기기