7장. 셸 스크립트 프로그래밍
CentOS의 bash 셸 [p410] 기본 셸은 bash(Bourne Again SHell : ‘배시 셸’) •Alias 기능(명령어 단축 기능) •History 기능(위/아래 화살표키) •연산 기능 •Job Control 기능 •자동 이름 완성 기능(탭키) •프롬프트 제어 기능 •명령 편집 기능 셸의 명령문 처리 방법 (프롬프트) 명령어 [옵션…] [인자…] 예) # rm -rf /mydir
환경 변수 [p411] “echo $환경변수이름” 으로 확인 가능 “export 환경변수=값” 으로 환경 변수의 값을 변경 주요 환경변수
셸 스크립트 프로그래밍 [p412] C언어와 유사하게 프로그래밍이 가능 변수, 반복문, 제어문 등의 사용이 가능 별도로 컴파일하지 않고 텍스트 파일 형태로 바로 실행 vi나 gedit으로 작성이 가능 리눅스의 많은 부분이 셸 스크립트로 작성되어 있음
셸 스크립트의 작성과 실행 [p412~p414] vi나 gedit으로 작성 실행 방법 “sh <스크립트 파일>”로 실행 “chmod +x <스크립트 파일>” 명령으로 실행 가능 속성으로 변 경한 후에, “./<스크립트파일>”명령으로 실행 셸 스크립트 파일의 확장명은 되도록 *.sh로 주는 것이 좋다. 셸 스크립트 파일을 /usr/local/bin/ 디렉토리에 복사하고, 속성을 755로 변경해 주면 모든 사용자가 스크립트를 사용할 수 있다. 이 작업은 보안상 root만 수행함
변수의 기본 [p415] 변수를 사용하기 전에 미리 선언하지 않으며, 변수에 처 음 값이 할당되면서 자동으로 변수가 생성 모든 변수는 ‘문자열(String)’로 취급 변수 이름은 대소문자를 구분 변수를 대입할 때 ‘=’좌우에는 공백이 없어야 함
변수의 입력과 출력 [p416] ‘$’ 문자가 들어간 글자를 출력하려면 ‘ ’로 묶어주거나 앞에 ‘\’를 붙임. ‘$’ 문자가 들어간 글자를 출력하려면 ‘ ’로 묶어주거나 앞에 ‘\’를 붙임. “ ”로 변수를 묶어줘도 된다. 01 #!/bin/sh 02 myvar="Hi Woo" 03 echo $myvar 04 echo "$myvar" 05 echo '$myvar' 06 echo \$myvar 07 echo 값 입력 : 08 read myvar 09 echo '$myvar' = $myvar 10 exit 0
숫자 계산 [p417] 변수에 대입된 값은 모두 문자열로 취급 변수에 들어 있는 값을 숫자로 해서 +, -, *, / 등의 연산을 하 려면 expr을 사용 수식에 괄호 또는 곱하기(*)는 그 앞에 꼭 역슬래쉬(\) 붙임 01 #!/bin/sh 02 num1=100 03 num2=$num1+200 04 echo $num2 05 num3='expr $num1 + 200' 06 echo $num3 07 num4='expr \($num1 + 200 \) / 10 \* 2' 08 echo $num4' 09 exit 0
파라미터(Parameter) 변수 [p418] 파라미터 변수는 $0, $1, $2…의 형태를 가짐 전체 파라미터는 $*로 표현 예) 01 #!/bin/sh 02 echo "실행파일 이름은 <$0>이다" 03 echo "첫번째 파라미터는 <$1>이고, 두번째 파라미터는 <$2>다" 04 echo "전체 파라미터는 <$*>다" 05 exit 0
기본 if 문 [p419] 형식 if [ 조건 ] then 참일 경우 실행 fi 01 #!/bin/sh 02 if [ "woo" = "woo" ] 03 then 04 echo "참입니다" 05 fi 06 exit 0 “[ 조건 ]”의 사이의 각 단어에는 모두 공백이 있어야 한다
if~else 문 [p420] 형식 01 #!/bin/sh 02 if [ "woo" != "woo" ] 03 then 참일 경우 실행 else 거짓인 경우 실행 fi 01 #!/bin/sh 02 if [ "woo" != "woo" ] 03 then 04 echo "참입니다" 05 else 06 echo "거짓입니다" 07 fi 08 exit 0 중복 if 문을 위해서 else if가 합쳐진 elif문도 사용할 수 있다.
조건문에 들어가는 비교 연산자 [p421] 01 #!/bin/sh 02 if [ 100 -eq 200 ] 03 then 04 echo "100과 200은 같다." 05 else 06 echo "100과 200은 다르다." 07 fi 08 exit 0
파일과 관련된 조건 [p422] 01 #!/bin/sh 02 fname=/lib/systemd /system/httpd.service 03 if [ -f $fname ] 04 then 05 head -5 $fname 06 else 07 echo "웹 서버가 설치되지 않았습니다." 08 fi 09 exit 0
case~esac 문 (1) [p423] if 문은 참과 거짓의 두 경우만 사용 (2중분기) 01 #!/bin/sh 02 case "$1" in 03 start) 04 echo "시작~~";; 05 stop) 06 echo "중지~~";; 07 restart) 08 echo "다시 시작~~";; 09 *) 10 echo "뭔지 모름~~";; 11 esac 12 exit 0
case~esac 문 (2) [p424] 01 #!/bin/sh 02 echo "리눅스가 재미있나요? (yes / no)" 03 read answer 04 case $answer in 05 yes | y | Y | Yes | YES) 06 echo "다행입니다." 07 echo "더욱 열심히 하세요 ^^";; 08 [nN]*) 09 echo "안타깝네요. ㅠㅠ";; 10 *) 11 echo "yes 아니면 no만 입력했어야죠" 12 exit 1;; 13 esac 14 exit 0
AND, OR 관계 연산자 [p425] and는 ‘-a’ 또는 ‘&&’를 사용 or는 ‘-o’ 또는 ‘||’를 사용 01 #!/bin/sh 02 echo "보고 싶은 파일명을 입력하세요." 03 read fname 04 if [ -f $fname ] && [ -s $fname ] ; then 05 head -5 $fname 06 else 07 echo "파일이 없거나, 크기가 0입니다." 08 fi 09 exit 0
반복문 – for문 (1) [p426] 형식 for 변수 in 값1 값2 값3 … do 반복할 문장 done 01 #!/bin/sh 02 hap=0 03 for i in 1 2 3 4 5 6 7 8 9 10 04 do 05 hap='expr $hap + $i' 06 done 07 echo "1부터 10까지의 합: "$hap 08 exit 0 3행은 for((i=1;i<=10;i++)) 또는 for i in ‘seq 1 10’ 로 변경 할 수 있음
반복문 – for문 (2) [p427] 현재 디렉터리에 있는 셸 스크립트 파일(*.sh)의 파일명 과 앞 3줄을 출력하는 프로그램 01 #!/bin/sh 02 for fname in $(ls *.sh) 03 do 04 echo "--------$fname-------" 05 head -3 $fname 06 done 07 exit 0
반복문 – while문 (1) [p428] 조건식이 참인 동안에 계속 반복 01 #!/bin/sh 02 while [ 1 ] 03 do 04 echo “CentOS 7" 05 done 06 exit 0 [ 1 ] 또는 [ : ]가 오면 항상 참이 됨. 그러므로 4행을 무한 루프로 반복함.
반복문 – while문 (2) [p429] 1에서 10까지의 합계를 출력 (‘반복문 – for문 (1)’ 슬라 이드와 동일) 01 #!/bin/sh 02 hap=0 03 i=1 04 while [ $i -le 10 ] 05 do 06 hap='expr $hap + $i' 07 i='expr $i + 1' 08 done 09 echo "1부터 10까지의 합 : "$hap 10 exit 0 until 문은 조건식이 참일 때까지(= 거짓인 동안) 계속 반복 4행을 until 문으로 바꾸면, until [ $i -gt 10 ]
반복문 – while문 (3) [p430] 비밀번호를 입력받고, 비밀번호가 맞을 때까지 계속 입 력받는 스크립트 01 #!/bin/sh 02 echo "비밀번호를 입력하세요." 03 read mypass 04 while [ $mypass != "1234" ] 05 do 06 echo "틀렸음. 다시 입력하세요." 07 read mypass 08 done 09 echo "통과~~" 10 exit 0
until 문 [p430] while문과 용도가 거의 같지만, until문은 조건식이 참일 때까지(=거짓인 동안) 계속 반복한다. while2.sh를 동일한 용도로 until문으로 바꾸려면 4행을 다음과 같이 바꾸면 된다. until [ $i -gt 10 ]
break, continue, exit, return 문 [p431] 01 #!/bin/sh 02 echo "무한반복 입력을 시작합니다(b: break, c: continue, e: exit)" 03 while [ 1 ] ; do 04 read input 05 case $input in 06 b | B ) 07 break ;; 08 c | C ) 09 echo "continue를 누르면 while의 조건으로 돌아감" 10 continue ;; 11 e | E ) 12 echo "exit를 누르면 프로그램(함수)를 완전히 종료함" 13 exit 1 ;; 14 esac; 15 done 16 echo "break를 누르면 while을 빠져나와 지금 이 문장이 출력됨." 17 exit 0
사용자 정의 함수 [p432] 형식 함수이름 ( ) { → 함수를 정의 내용들… } 함수이름 → 함수를 호출 01 #!/bin/sh 02 myFunction () { 03 echo "함수 안으로 들어 왔음" 04 return 05 } 06 echo "프로그램을 시작합니다." 07 myFunction 08 echo "프로그램을 종료합니다." 09 exit 0
함수의 파라미터 사용 [p433] 형식 함수이름 ( ) { → 함수를 정의 $1, $2 … 등을 사용 } 함수이름 파라미터1 파라미터2 … → 함수를 호출 01 #!/bin/sh 02 hap () { 03 echo 'expr $1 + $2' 04 } 05 echo "10 더하기 20을 실행합니다" 06 hap 10 20 07 exit 0
eval [p434] 문자열을 명령문으로 인식하고 실행 01 #!/bin/sh 02 str="ls -l anaconda-ks.cfg" 03 echo $str 04 eval $str 05 exit 0
export [p434] 외부 변수로 선언해 준다. 즉, 선언한 변수를 다른 프로그램에 서도 사용할 수 있도록 해줌 exp1.sh 01 #!/bin/sh 02 echo $var1 03 echo $var2 04 exit 0 exp2.sh 02 var1="지역 변수" 03 export var2="외부 변수" 04 sh exp1.sh 05 exit 0
printf [p435] C언어의 printf() 함수와 비슷하게 형식을 지정해서 출력 01 #!/bin/sh 02 var1=100.5 03 var2="재미있는 리눅스~~" 04 printf "%5.2f \n\n \t %s \n" $var1 "$var2" 05 exit
set과 $(명령어) [p436] 리눅스 명령어를 결과로 사용하기 위해서는 $(명령어) 형식을 사용 리눅스 명령어를 결과로 사용하기 위해서는 $(명령어) 형식을 사용 결과를 파라미터로 사용하고자 할 때는 set과 함께 사용 01 #!/bin/sh 02 echo "오늘 날짜는 $(date) 입니다." 03 set $(date) 04 echo "오늘은 $4 요일 입니다." 05 exit 0
shift (1) [p437] 파라미터 변수를 왼쪽으로 한 단계씩 아래로 쉬프트시킴 10개가 넘는 파라미터 변수에 접근할 때 사용 단, $0 파라미터 변수는 변경되지 않음 원하지 않는 결과의 소스 01 #!/bin/sh 02 myfunc () { 03 echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 04 } 05 myfunc AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK 06 exit 0
shift (2) [p438] shift 사용을 통한 앞 문제점을 해결 01 #!/bin/sh 02 myfunc() { 03 str="" 04 while [ "$1" != "" ] ; do 05 str="$str $1" 06 shift 07 done 08 echo $str 09 } 10 myfunc AAA BBB CCC DDD EEE FFF GGG HHH III JJJ KKK 11 exit 0