0402_Linux_Shell Programming_제어문 (2)_반복문
조건문
- 조건에 따라 수행할 동작을 지정
- if : 조건이 맞으면 실행, 아니면 패스
- if~else : 조건이 맞으면 if 아래를 실행, 조건이 틀리면 else 아래를 실행, 양자택일
- if~else if~else : 조건이 여러개. 첫 번째 조건이 맞으면 if 아래를 실행, 두번째 조건이 맞으면 두번째 else if 아래를 실행. 모든 조건이 틀리면 else 아래를 실행. 다지선다
- 조건문의 문법 : if, then, fi
if (조건) then (if 실행할 내용) fi |
if (조건) then (if 실행할 내용) else (else 실행할 내용) fi |
if (조건1) then (if 조건1에 따라 실행할 내용) elif (조건2) then (elif의 조건2에 따라 실행할 내용) elif (조건3) then (elif의 조건3에 따라 실행할 내용) … else (모든 조건을 만족하지 않을 경우 실행할 내용) fi |
case = if~else if~else 와 유사한 동작. 다지선다
case 변수명 in 값1) 실행할 내용1 ;; 값2) 실행할 내용2 ;; 값3) 실행할 내용3 ;; *) 실행할 내용4 esac |
쉘 프로그래밍의 조건문에서의 ‘조건’
- 명령의 실행 결과가 if의 조건으로 사용됨 : 종료상태(Exit Status)
- 정상종료 : 0 (true)
- 비정상종료 : 0이 아닌 모든 값 (false)
- 일반적인 수치비교, 문자, 문자열 비교 : test
- 수치비교
- == : INT1 -eq INT2 (equal)
- != : INT1 -ne INT2 (not equal)
- > : INT1 -gt INT2 (greater than)
- < : INT1 -lt INT2 (less than)
- >= : INT1 -ge INT2 (greater or equal)
- <= : INT1 -le INT2 (less or equal)
- 문자비교
- 문자열1 = 문자열2 : 문자열 1과 2가 같으면 참
- 문자열1 != 문자열2 : 문자열 1과 2가 같지 않으면 참
- 문자열 : 문자열이 NULL 이 아니면 참, NULL 이면 거짓
- -z 문자열 : 문자열의 길이가 0이면 참, 아니면 거짓
- -n 문자열 : 문자열의 길이가 0이 아니면 참, 아니면 거짓
- test 명령어는 [ ] 로 대체 가능
- ksh, bash 등 이후에 나온 쉘은 다음과 같은 기능도 사용가능
- [[ ]] 를 사용하여 단순 비교 이외의 비교도 가능
- [[ 문자열 = 패턴 ]] : 문자열에 패턴이 포함되어 있는가
- [[ 문자열 != 패턴 ]] : 문자열에 패턴이 포함되지 않았는가
- [[ 문자열1 > 문자열2 ]] : 문자열1과 2의 ASCII 대소비교
- STR1=AA; STR2=AB
- [[ $STR1 > $STR2 ]]; echo $?
- let을 사용하여 간단한 수치비교 가능 (( ))
- (( 변수1 > 숫자 )) : 변수의 값이 숫자보다 큰가
- (( 변수1 = 변수2 + 변수3 ))
- (( NUM3=NUM1+NUM2 ))
- 파일관련 조건 확인
- [옵션] [파일명]
- 옵션
- -b : 블록 장치인지 확인
- -c : 캐릭터 장치인지 확인
- -d : 디렉토리인지 확인
- -e : 종류에 상관없이 파일이 있는지 확인
- -f : 일반 파일인지 확인
- -r : test를 수행하는 사람이 파일의 읽기 권한을 가지고 있는가
- -w : test를 수행하는 사람이 파일의 쓰기 권한을 가지고 있는가
- -x : test를 수행하는 사람이 파일의 실행 권한을 가지고 있는가
- -u : SetUID 가 설정되어 있는가
- -g : SetGID가 설정되어 있는가
- -k : StickyBit가 설정되어 있는가
- test 사용시 조건의 논리합/논리곱
- [ 조건1 -a 조건2 ] : 조건1과 조건2를 모두 만족하여야 참
- [[ 조건1 && 조건2 ]] : 위와 동일
- [ 조건1 -o 조건2 ] : 조건1과 조건2중 하나만 만족하면 참
- [[ 조건1 || 조건2 ]] : 위와 동일
- /usr/bin/true, /usr/bin/false : 다른 역할은 하지 않으면서 종료상태만 변경
- ‘ : ’ : true 와 같은 역할
case 테스트
#!/bin/bash echo "Input Fruits name : " read FRUIT if [ $FRUIT = 'apple' ] then echo "APPLE" elif [ $FRUIT = 'banana' ] then echo "banana" else echo "cherry" fi case $FRUIT in apple) echo APPLE ;; banana) echo BANANA ;; *) echo cherry ;; esac |
연습문제
- 파일명을 입력받고, 입력받은 파일의 종류(일반파일, 디렉토리, 블록장치, 캐릭터장치…)가 무엇인지 출력하는 스크립트를 작성해보세요.
input filename : /etc/passwd /etc/passwd : normal file input filename : /dev/sda /dev/sda : block device file input filename : /tmp /tmp : directory |
- 숫자 두개와 연산자를 입력받아 계산 결과를 출력하는 프로그램을 작성해보세요\
input number: 10 input number: 20 operator : + 10 + 20 = 30 |
- df -h 명령을 사용해서 확인할 수 있는 ‘/’ 에 마운트된 장치의 사용량이 50%를 초과할 경우 메세지를 출력하는 프로그램을 작성하시오.
/dev/mapper/centos-root 47G 5.7G 42G 13% / ‘/’ USE% is under 50% |
/dev/mapper/centos-root 47G 5.7G 42G 53% / ‘/’ USE% is over 50% |
q1.sh |
#!/bin/bash echo -n "Input filename : " read FILENAME if [ -f $FILENAME ] then echo "$FILENAME : normal file" elif [ -d $FILENAME ] then echo "$FILENAME : directory" elif [ -b $FILENAME ] then echo "$FILENAME : block device file" elif [ -c $FILENAME ] then echo "$FILENAME : character device file" else echo "I don't know" fi |
q2.sh |
#!/bin/bash echo -n "Input number1 : " read NUM1 echo -n "Input number2 : " read NUM2 echo -n "Input operator : " read OPER case $OPER in '+') echo "$NUM1 + $NUM2 = `expr $NUM1 + $NUM2`" ;; '-') echo "$NUM1 - $NUM2 = `expr $NUM1 - $NUM2`" ;; '/') echo "$NUM1 / $NUM2 = "`echo "scale=2;$NUM1/$NUM2" | bc` ;; '*') echo "$NUM1 X $NUM2 = `expr $NUM1 \* $NUM2`" ;; *) echo "ERROR!" ;; esac |
q3.sh |
#!/bin/bash DFRESULT="/dev/mapper/centos-root 47G 5.7G 42G 63% /" echo "SAMPLE: $DFRESULT" USEPERCENT=`echo $DFRESULT | awk '{ print $5 }'` echo "Current USE% : "$USEPERCENT USEPERCENT=`echo ${USEPERCENT:0:-1}` if (( USEPERCENT>50 )) then echo "OVER 50%!" else echo "UNDER 50%!" fi |
=============================================================
반복문 (Loop)
- 지정한 회수, 또는 조건에 따라 반복을 수행
- for 반복문
for(i=0;i<10;i++){ printf(“Hello!\n”) } |
C언어 등 일반적인 프로그래밍 언어의 반복문의 조건 형태
- 초기식 : 특정 변수를 초기값으로 설정
- 비교식 : 반복여부를 결정하기 위하여 조건을 확인
- 증감식 : 조건에 사용되는 변수의 값을 변경
쉘 프로그래밍의 반복문 : for
for 변수 in [argument] do [실행할내용] done |
#!/bin/bash for i in `ls` do echo $i done |
argument : 반복문에서 변수에 집어넣을 값의 리스트
- 공백,개행 등으로 구분되어 있는 텍스트
- 명령의 실행결과 : `명령어`
- 파일의 내용 : `cat [파일이름]`
- 변수의 값 : $변수명
- 위치매개변수 : $*, $@, “$*”, “$@”
위치매개변수를 반복문의 argument로 사용할 경우
- $*, $@ : 각 위치매개변수의 값을 그대로 나열하므로, 사이에 공백이 들어있는 하나의 매개변수를 분리함
- “$*” : 전체 위치매개변수의 값을 하나의 문자열로 처리
- “$@” : 위치매개변수 중 공백을 포함하고 있는 항목만 따로 ‘ ‘ 로 묶어서 처리
#!/bin/bash for i in $* for i in $@ for i in "$*" for i in "$@" do echo $i done |
argument에 숫자 사용방법
- 단순 숫자 나열 : 직접 반복문에 사용할 변수에 집어넣을 숫자를 나열
- seq 명령 사용
- seq [숫자] : 1부터 지정한 숫자까지 1씩 증가하며 출력
- seq [숫자1] [숫자2] : 숫자1 부터 숫자2까지 1씩 증가하며 출력
- seq [숫자1] [숫자2] [숫자3] : 숫자 1부터 숫자 3까지 숫자2 만큼씩 증가시키며 출력
- 다른 프로그래밍 언어의 for 구문과 유사한 사용방법
- for ((초기식;조건식;증감식))
#!/bin/bash for i in `seq 20 -2 0` do echo "NUM = $i" done |
#!/bin/bash for ((i=0;i<10;i++)) do echo "NUM = $i" done |
- while
while [조건] do [실행할 내용] done |
while의 동작
- while 내부 명령을 실행하기 전 조건을 확인
- 조건을 만족할 경우 (참일 경우) 실행
- 조건을 만족하지 않을 경우 done 아래로 이동
- 조건을 true 등 언제나 참인 조건으로 사용할 경우는 무한루프로 동작
- 사용자가 입력하는 값을 변수에 집어넣어서 비교하여 종료하는 방식
#!/bin/bash VAR=0 while [ $VAR -le 10 ] do echo $VAR VAR=`expr $VAR + 1` done |
#!/bin/bash STR=n while [ $STR != y] do echo -n "Quit (y/n)? " read STR done |
- until : while 의 반대. 조건이 거짓일 경우에 반복 수행
until [조건] do [실행할 내용] done |
- 중첩 반복문 / break / continue
중첩 반복문
- 반복문 내부에 반복문이 포함되는 형태
- 내부 반복문은 외부 반복문이 한번 실행될 때마다 전체 반복을 수행
- 구구단 : 단 / 곱할 수
- 반복문1(단을 올리는 반복문)
do 반복문2 (곱할수를 올리는 반복문) do vi구구단 출력 done done |
#!/bin/bash for i in `seq 2 9` do for j in `seq 2 9` do echo "$i X $j = `expr $i \* $j`" done done |
break : 반복문을 탈출하는 용도
- 반복문을 탈출하는 용도 (if 내에서 탈출하는 용도로는 사용할 수 없음)
- 탈출위치는 현재 break가 사용된 반복문의 done 아래로 이동
- 중첩 반복문에서 사용될 경우, 한 단계의 반복문만 탈출
- break [숫자] : 한꺼번에 지정한 개수만큼의 반복문 탈출
- exit : 반복문이 아니라 스크립트 전체를 종료
- exit [숫자] : 스크립트를 종료하면서 종료상태값을 설정
while true do echo -n "Quit? (y/n) : " read STR if [ $STR = "y" ] then break fi done |
for i in `seq 2 9` do for j in `seq 2 9` do if [ $j -gt 5 ] then # break 반복문 탈출 # break 2 반복문 2개 탈출 # exit 모든 반복문 즉시 탈출 fi echo "$i X $j = `expr $i \* $j`" done done |
for i in `seq 2 9` do for j in `seq 2 9` do if [ $j -gt 5 ] then break fi echo "$i X $j = `expr $i \* $j`" done done # exit 0 스크립트 종료 후 종료 상태값 0으로 설정 # exit 1 스크립트 종료 후 종료 상태값 1로 설정 |
continue
- 반복문의 흐름을 변경시키는 용도
- continue를 만날 경우, 현재 있는 반복문의 조건 위치로 이동(do 앞으로)
- continue [숫자] : 한꺼번에 지정된 개수만큼의 반복문 위로 올라감
#!/bin/bash for i in 2 3 4 5 6 7 8 9 do for j in 1 2 3 4 5 6 7 8 9 do if [ $j -eq 5 ] then # continue # continue 2 fi echo "$i X $j ="`expr $i \* $j` done done |
q1) 어제 실습한 내용 중 숫자 입력받고 연산자 입력받아서 계산하는 프로그램
=> 위치매개변수를 사용하여 계산하도록
$ ./myexpr.sh 10 + 3 10 + 3 = 13 $ ./myexpr.sh 10 / 3 10 / 3 = 3.33 |