1. For 명령어
For 명령어는 반복적인 일을 처리할때 아주 유용한 명령어 입니다. 사용구문은 아래와 같습니다.
for var in list
do
commands
done
반복적인 변수의 입력은 list를 통해서 제공을 해야 됩니다. do 와 done 사이에 실행할 명령어들을 입력을 시킵니다.
List에서 변수값 읽기
리스트를 사용하는 방법 중 하나는 아래와 같이 space로 값들을 분리 하여 나열하는 방법 입니다.
#! /bin/bash
# for 문에서 list 사용하는 예제
for test in seoul busan daegu daejun incheon kwangju
do
echo the next city is $test
done
#
실행을 시켜보면 아래와 같이 도시명들이 한줄씩 출력이 되는걸 볼수 있습니다.
$ ./test1
the next city is seoul
the next city is busan
the next city is daegu
the next city is daejun
the next city is incheon
the next city is kwangju
입력되는 변수에 싱글따옴표가 있을경우에는 앞에 백슬러쉬를 붙여 주던가 아니면 쌍따옴표로 묶어야 하나의 변수 값으로 취급이 됩니다.
예제를 하나 만들어 보면 아래와 같이 동작을 합니다.
#!/bin/bash
# another example of how not to use the for command
for test in I don’t know if this’ll work
do
echo "word:$test"
done
#
실행을 시켜 보면 싱글따옴표 묶음을 (dont know it thisll) 하나의 변수로 취급을 합니다. 이를 피하기 위해서는 쌍도움표로 묶어 주던지 아니면 싱글따움표 앞에 백슬러쉬로 처리를 해워야 합니다.
$ ./badtest1
word:I
word:dont know if thisll
word:work
$
변수로 부터 리스트값응 읽기.
변수에 여러개의 값을 넣고 리스트에 저장을 하면 변수값을 나열하는 것과 동일한 효과를 볼수 있습니다.
예제를 하나 살펴 봅시다.
#! /bin/bash
# for 문에서 list 사용하는 예제
list="seoul busan daegu daejun incheon kwangju"
city=$list
for test in $city
do
echo the next city is $test
done
실행을 시켜보면
$ ./test2
the next city is seoul
the next city is busan
the next city is daegu
the next city is daejun
the next city is incheon
the next city is kwangju
명령어로 부터 값 읽기
명령어의 출력 결과로 부터도 값을 읽어 들일수가 있는데요. 백틱(`)을 이용해 수행할 명령을 지정을 해주면 그 출력 결과를 for문 안에서 사용이 가능합니다. 예를 한번 살펴 보겠습니다. 우선 city라는 파일에 도시명을 아래와 같이 입력을 해놓았 습니다.
$ cat city
seoul
busan
daegu
kwangju
tongyoung
스크립트를 아래와 같이 작성을 합니다.
#! /bin/bash
# 파일로 부터 입력값 읽어 들이기
file="city" ==> file 변수에 city의 파일명을 입력
for city in `cat $file` ==> 백틱으로 둘러싸인 cat명령이 file에 저장된 파일을 읽음
do
echo "Visit place is $city"
done
실행을 시켜 보면 아래와 같이 잘 실행되는 것을 볼수 있습니다.
$ ./test3
Visit place is seoul
Visit place is busan
Visit place is daegu
Visit place is kwangju
Visit place is tongyoung
필드 구분자 변경해 사용하기
리눅스에서는 Shell이 사용하는 필드 구분자의 정의가 IFS(Intenal Field Seperator)에 정의된 값대로 문자를 구분을 합니다. 기본적으로는 아래 3가지가 정의되어 있습니다.
■ A space
■ A tab
■ A newlin
Shell이 위의 3가지 중에 하나를 만나면 새로운 데이터가 시작이 된다고 간주를 합니다.
스크립트 작성시 변경하는 방법의 예제를 만들어 보겠습니다. IFS값을 new line으로 설정할 경우 입니다.
#!/bin/bash
# reading values from a file
file="states"
IFS=$’\n’
for state in `cat $file`
do
echo "Visit beautiful $state"
done
위와 같이 사용을 하면 space나 tab은 무시가 되고 데이터 구분자로 뉴라인만 사용하게 됩니다. 주의할점은 IFS를 변경 한후에 잊어 버리고 기본값으로 복구를 하지 않아 발생하는 경우가 많습니다. 이를 위해 스크립트 상에 아래와 같은 복구 코드를 작성해 두는 것이 좋습니다.
#
IFS.OLD=$IFS
IFS=$’\n’
‹use the new IFS value in code›
IFS=$IFS.OLD
#
가장 많이 사용되는 구분자로 세미콜론이 있는데요, 이를 사용하기 위해서는 ifs=; 으로 설정을 해주면 데이터가 세미콜론 단위로 분리가 됩니다. IFS 여러개의 구분자를 사용하고 싶은 경우에는 필드 구분자를 나열을 해주면 됩니다.
예를 들면 IFS=$'\n':;" ==> 구분자가 뉴라인, 콜론, 쎄미콜론, 쌍따움표를 사용.
와일드 카드를 사용하여 디렉토리 읽어 들이기
가끔 디렉토리에 어떤 파일들이 있는지 모두 읽어 들여서 어떤 작업을 하고 싶을때 와일드 카드를 사용하여 이러한 작업을 실행할 수 있습니다. 예제를 한번 보겠 습니다. 그리고 여러개의 디렉토리를 검사하고 싶을경우에는 in 다음ㅇ에 디렉토리들을 space로 구분하여 열거해 주면 됩니다.
#! /bin/bash
#와일드 카드를 이용한 디렉토리 읽어 들이기
for wild in /home/hyowon/*
do
if [ -d "$wild" ]
then
echo "$wild is a directory"
else [ -f "$file" ]
echo "$wild is a file"
fi
done
#
실행을 시켜 보면
$ ./test4
/home/hyowon/NPKI is a directory
/home/hyowon/Steam is a directory
/home/hyowon/VirtualBox VMs is a directory
/home/hyowon/deja-dup is a directory
/home/hyowon/dir.Iu6oW4 is a directory
/home/hyowon/dir.d03tYD is a directory
/home/hyowon/kdenlive is a directory
/home/hyowon/path is a directory
/home/hyowon/snap is a directory
/home/hyowon/test is a directory
/home/hyowon/test12 is a directory
/home/hyowon/workspace is a directory
/home/hyowon/공개 is a directory
/home/hyowon/다운로드 is a directory
/home/hyowon/문서 is a directory
/home/hyowon/바탕화면 is a directory
/home/hyowon/비디오 is a directory
/home/hyowon/사진 is a directory
/home/hyowon/음악 is a directory
/home/hyowon/템플릿 is a directory
2. C언어 스타일 사용하기
Shell에서 C 언어의 프로그래밍 형식을 지원합니다. 그 중 한가지 예를 보면 아래와 같습니다.
#!/bin/bash
# testing the C-style for loop
for (( i=1; i ‹= 10; i++ ))
do
echo "The next number is $i"
done
#
선언문에서 여러개의 변수도 사용이 가능 합니다. 사용 방법은 아래와 같습니다.
#!/bin/bash
# testing the C-style for loop
for (( i=1; i ‹= 10; i++ ))
do
echo "The next number is $i"
done
#
3. While 명령어 사용하기
while명령어는 if-then와 for문의 효과를 같이 볼수 있는 명령어라고 생각을 하면 될것 같습니다.
사용 구문은 아래와 같습니다. 그리고 여러개의 테스트 문을 사용하고 싶으면 space로 구분된 테스트문을 while 구문에 나열하여 주면 됩니다.
예제
#
while test command ==> test command 가 true일 동안 반복적으로 other command를 실행
do
other commands
done
#
예제 스크립트를 하나 보겠습니다.
$ cat test10
#!/bin/bash
# while command test
var1=10
while [ $var1 -gt 0 ] ==> var1의 값이 0보다 클때까지 계속 반복
do
echo $var1 ==> var1을 출력을 하고
var1=$[ $var1 - 1 ] ==> var1의 값을 하나 감소 시킵니다.
done
실행을 시켜 보면
$ ./test10
10
9
8
7
6
5
4
3
2
1
$
4. until 명령어
until 명령은 while 명령어와 정 반대로 동작하는 명령어 입니다. exit code가 0이 아닌경우 반복작업을 지속 합니다. 아래와 같이 예제를 살펴 보겠습니다.
#!/bin/bash
# using the until command
var1=100
until [ $var1 -eq 0 ] ==> var1이 0과 같을 때까지 do아래의 명령을 반복 실행 합니다.
do
echo $var1
var1=$[ $var1 - 25 ]
done
#
실행을 시켜 보면
$ ./test
100
75
50
25
$
5. 중복 루프문
중복 루프문은 루프 안에서 또 다른 루프문을 실행하게 해줍니다. 예제를 아래와 같이 살펴 봅시다.
#!/bin/bash
# placing a for loop inside a while loop
var1=5
while [ $var1 -ge 0 ] ==> var1의 값이 0과 같거나 클때까지 반복
do
echo "Outer loop: $var1"
for (( var2 = 1; $var2 ‹ 3; var2++ )) ==> inner루프, var2의 값이 3보다 작을때 계속 반복.
do
var3=$[ $var1 * $var2 ]
echo " Inner loop: $var1 * $var2 = $var3"
done
var1=$[ $var1 - 1 ]
done
#
실행을 시켜 보면.
$ ./test5
Outer loop 5
Inner loop: 5 * 1=5
Inner loop: 5 * 2=10
Outer loop 4
Inner loop: 4 * 1=4
Inner loop: 4 * 2=8
Outer loop 3
Inner loop: 3 * 1=3
Inner loop: 3 * 2=6
Outer loop 2
Inner loop: 2 * 1=2
Inner loop: 2 * 2=4
Outer loop 1
Inner loop: 1 * 1=1
Inner loop: 1 * 2=2
Outer loop 0
Inner loop: 0 * 1=0
Inner loop: 0 * 2=0
6. 파일데이터 반복 검색
가끔 파일 안의 데이터를 반복적으로 처리를 해야 되는 경우가 있습니다. 이 경우 처리 하는 방법이 크게 아래와 같이 2가지의 방법이 있습니다.
■ 중복 반복문 사용
■ IFS 값을 변경
/etc/passwd 파일을 검색하는 예제를 만들고 실행해 보도록 하겠습니다.
#! /bin/bash
#IFS값 변경 후 이중 루프 돌리기
IFS.OLD=$IFS
IFS=$'\n'
for entry in `cat /etc/passwd`
do
echo "Values in $entry"
IFS=:
for values in $entry
do
echo " $values"
done
done
실행을 시켜 보면
$ ./test6
Values in root:x:0:0:root:/root:/bin/bash
root
x
0
0
root
/root
/bin/bash
Values in daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
daemon
x
1
1
daemon
/usr/sbin
/usr/sbin/nologin
Values in bin:x:2:2:bin:/bin:/usr/sbin/nologin
7. Loop 제어하기
반복문이 실행이 될때 루프를 제어 할수 있는 방법이 있습니다. 그 방법은 아래 명령을 사용하여 스크립트를 작성하면 됩니다.
■ break 명령어 : 루프를 빠져 나갑니다.
■ continue 명령어 : 루프를 빠져 나가지 않고 다음 루프를 실행 시킵니다.
break 명령어 사용예제
1)for문에서의 반복문 탈출 예제
#!/bin/bash
# breaking out of a for loop
for var1 in 1 2 3 4 5 6 7 8 9 10
do
if [ $var1 -eq 5 ] ===> var1값이 5일때
then
break ==> loop를 빠져 나갑니다.
fi
echo "Iteration number: $var1"
done
echo "The for loop is completed"
실행을 시켜 보면
$ ./test17
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
The for loop is completed
$
2)until문에서의 사용 예제
#!/bin/bash
# breaking out of a while loop
var1=1
while [ $var1 -lt 10 ]
do
if [ $var1 -eq 5 ]
then
break
fi
echo "Iteration: $var1"
var1=$[ $var1 + 1 ]
done
echo "The while loop is completed"
#
실행을 시켜 보면
$ ./test18
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
The while loop is completed
$
3)중복 반복문에서 내부 반복문 빠져 나오기
#!/bin/bash
# breaking out of an inner loop
for (( a = 1; a ‹ 4; 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
#
실행을 시켜 보면
$ ./test1
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
$
4)내부 루프에서 외부 루프까지 빠져 나오기
중복 반복문에서 break n 명령은 중복 루프를 한꺼번에 빠져 나올수 있는 방법을 제공하고 있습니다.
위의 예제에서 내부 루프에서 빠져 나와도 바깥 루프는 그대로 반복이 됩니다. 하지만 만약 위의 스크립트에서 break 2를 입력 하였다면 바깥 루프도 종료 되게 됩니다.
여기서 n은 몇단계를 빠져 나올지 정해주는 파라메터 값입니다
continue 명령어 사용하기
이 명령은 루프를 종료 시키지는 않고 continu가 걸리는 조건상에서 test를 생략하고 다음 루프로 넘어가게 하는 명령 입니다. 예제를 아래와 같이 살펴 봅시다.
#!/bin/bash
# using the continue command
for (( var1 = 1; var1 ‹ 15; var1++ ))
do
if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] ==> var1의 >5, <10으면 echo문을 실행하지 않고 다음 루프로
then
continue
fi
echo "Iteration number: $var1"
done
실행을 시켜 보면 6에서 9까지는 echo문이 실행이 되지 않습니다.
$ ./test21
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
Iteration number: 5
Iteration number: 10
Iteration number: 11
Iteration number: 12
Iteration number: 13
Iteration number: 14
$
continue도 break처럼 몇단계를 skip할지를 정할수 있습니다. 사용 방법은 continue n 값으로 지정을합니다.
예제를 한번 살펴 봅시다.
#!/bin/bash
# continuing an outer loop
for (( a = 1; a ‹= 5; a++ ))
do
echo "Iteration $a:"
for (( b = 1; b ‹ 3; b++ ))
do
if [ $a -gt 2 ] && [ $a -lt 4 ] ==> A의 값이 2보다 크가 4보다 작을때(3) 안쪽 루프에서 2단계(1,2) Skip
then
continue 2
fi
var3=$[ $a * $b ]
echo "The result of $a * $b is $var3"
done
done
실행 시켜 봅시다.
$ ./test
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
$
루프의 출력 처리
루프의 출력 처리는 pipe나 sort또는 redirect 명령어 등으로 파일로 저장을 할수도 있습니다.
아래 예제를 살펴 봅시다.
#! /bin/bash
for file in /home/rich/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif
echo "$file is a file"
fi
done > output.txt ==> 루프의 실행 결과를 output.txt 파일에 저장을 합니다.
다른 예제를 좀 살펴 봅시다.
#!/bin/bash
# piping a loop to another command
for state in "North Dakota" Connecticut Illinois Alabama Tennessee
do
echo "$state is the next place to go"
done | sort ===> 루프문의 처리결과를 sort 명령으로 파이프를 이용해서 알파벳 순으로 출력 합니다.
echo "This completes our travels"
실행을 해보면.
$ ./test24
Alabama is the next place to go
Connecticut is the next place to go
Illinois is the next place to go
North Dakota is the next place to go
Tennessee is the next place to go
This completes our travels
$
쉘 스크립트가 점점 어려워 지는 느낌이네요. 오늘은 여기까지 하겠습니다.
'쉘스크립트' 카테고리의 다른 글
데이터 표현하기 (2) | 2022.07.06 |
---|---|
사용자 입력 데이터 처리 (1) | 2022.07.06 |
구조화된 명령어들 (1) | 2022.07.06 |
기본 Shell 스크립트 작성 (1) | 2022.07.05 |
리눅스 파일 퍼미션 (1) | 2022.07.05 |