쉘스크립트

세부 구조적인 Shell 명령어

트리스탄1234 2022. 7. 6. 08:42
728x90
반응형

 

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

$

쉘 스크립트가 점점 어려워 지는 느낌이네요. 오늘은 여기까지 하겠습니다.

 
728x90
반응형

'쉘스크립트' 카테고리의 다른 글

데이터 표현하기  (2) 2022.07.06
사용자 입력 데이터 처리  (1) 2022.07.06
구조화된 명령어들  (1) 2022.07.06
기본 Shell 스크립트 작성  (1) 2022.07.05
리눅스 파일 퍼미션  (1) 2022.07.05