Chapter 05. 셸 (shell ) 관리 Solaris 3. 셸 스크립트 작성 솔라리스10 Chapter 05. 셸 (shell ) 관리 Solaris 3. 셸 스크립트 작성
1. 셸 스크립트의 이해 셸 스크립트는 읽기(read), 쓰기(write), 디버깅(debugging)으로 되어 있다. 셸 스크립트의 핵심요소 3가지 변수 설정에 대한 이해 ( 변수명=변수값 ) 위치인자에 대한 이해 ($0, $1, $2, $3 , $# , $@, $* .. ) 제어문 구조에 대한 이해 ( if, case, for, while )
2. 셸 스크립트의 작성 셸 스크립트 작성 요구 사항 루트 파일 시스템(/)의 사용률이 80%를 넘었을 경우 관리자에게 경고 메시지를 화면에 뿌리고 경고 메일을 보낸다. 80%가 넘지 않을 경우 30분 간격으로 체크한다. 1. 셸 스크립트를 작성할 셸 선택 ( #!/bin/ksh 2. 프로그램에 주석 달기 ( # 뒤에 주석 달기 ) 3. 명령어를 충분히 테스트하기 4. 변수 설정하기 5. 변수의 값을 확인하기 6. 셸 스크립트 퍼미션 변경하기 7. 셸 스크립트 실행하기
echo, print 명령어 테스트하기 쿼팅(Quoting)의 이해 문자열 보여주기 커서 입력대기 ( echo “문자열 \c “ ) ( print -n “ 문자열 “ ) 쿼팅(Quoting)의 이해 싱글 쿼트 ( ‘ ‘ ) : 문자 그대로 보여준다. 더블 쿼트 ( “ “ ) : 특수 문자의 의미를 일부는 해석하고 일부는 해석하지 않는다. 백쿼트 ( ` ` ) : 명령어를 실행한다. 역슬래쉬 ( \ ) : 바로뒤에 나오는 특수문자를 해석하지 않는다.
3. 셸 스크립트 디버깅 셸 스크립트는 인터프리터 언어(Interpreter Language)이기 때문에 에러가 나면 실행을 멈추고 어느 라인에서 에러가 났는지를 확인해 준다. # ksh -x 스크립트명 스크립트를 실행할 경우 –x 옵션을 사용하면 한줄씩 해석하면서 소스코드와 실행 결과를 한꺼번에 같이 보여준다. 스크립트 내에 set -x 라는 명령어를 넣어줘도된다.
4. 조건문 (if, case ) if 조건문 콘쉘(ksh) 조건식 숫자 비교 if 조건식(conditional Expressions) then 실행할 명령어 else fi 조건식 설명 (( $A > $B )) 숫자 A 가 B 보다 큰 경우 (( $A < $B )) 숫자 A 가 B 보다 작은 경우 (( $A >= $B )) 숫자 A 가 B 보다 크거나 같은 경우 (( $A <= $B )) 숫자 A 가 B 보다 작거나 같은 경우
콘셸 문자열 비교 콘셸 파일 테스트 조건식 설명 -f file 파일인지 테스트, 파일이면 참 파일이 아니면 거짓이다. [[ $VAR = 문자열 ]] 변수(VAR)의 값과 문자열이 같은지 비교 [[ $VAR != 문자열 ]] 변수(VAR)의 값과 문자열이 같지 않은지 비교 조건식 설명 -f file 파일인지 테스트, 파일이면 참 파일이 아니면 거짓이다. -d directory 디렉터리면 참, 아니면 거짓이다. -e file 파일이 존재하면 참, 없으면 거짓이다. -s file 파일의 크기가 0보다 크면 참, 0이면 거짓이다. -z $변수명 변수값이 있으면 참, 변수값이 없으면 거짓이다.
조건식 연산자 조건식 연산 기호 설명 조건식1 || 조건식2 조건식1이 참이거나 조건식2가 참이면 전체적으로 참이다. 조건식1 || 조건식2 조건식1이 참이거나 조건식2가 참이면 전체적으로 참이다. 조건식1 && 조건식2 조건식1과 조건식2가 참이어야 전체적으로 참이다. ! 조건식 조건식이 거짓이면 참이다. (조건식) 조건식이 여러 개일 경우 그룹을 지을 수 있다.
solaris10 # vi shell_07.ksh #!/bin/ksh # 루트파일시스템 사용량을 DISKUSAGE 변수에 넣는다. # ` ` 백쿼트는 명령어를 실행하라는 의미이다. 실행된 명령어의 결#과 값을 DISKUSAGE 변수에 설정한다. DISKUSAGE=`df -k | grep '\/$' | nawk '{print $5}' | sed 's/%//' ` # echo $DISKUSAGE if (( $DISUSAGE >= 80 )) then echo " 루트파일시스템이 80% 를 넘었습니다. 확인 요망 " mailx -s " 루트 파일 시스템 경고 " root << END 루트 파일시스템이 80%를 넘었습니다. 파일 시스템을 체크 하세요 !! END # END 문자 앞에 공백이 없다. fi solaris10 # chmod 755 shell_07.ksh
히어 도큐먼트 ( here document ) 명령어 << END 입력하고 싶을 문자열 입력하고 싶은 만큼 입력한다. END END 문자열은 프로그래머가 정할 수 있다. 두번째 END는 항상 라인의 처음에 와야 한다. 보기 좋게 하기 위해 공백을 앞에 주면 문법 에러가 난다.
조건문2. case 구문 case case "변수" in 변수값1| 변수값2) # 파이프( | ) 는 여러 개의 변수값이 동일한 명령어 실행될 명령어 # 를 실행할 경우 사용한다. ;; # case 구문에서 스크립트 블록이 종료될 때 더블 세미콜 # 론( ;; ) 을 사용한다. 변수값3) 실행될 명령어 ;; 변수값4) *) 실행될 명령어 # 주로 명령어 사용법을 기술한다. esac
banner.sh solaris10 # vi banner.ksh #!/bin/ksh case "$1" in start) banner start ;; stop) banner stop *) echo "Usage : $0 { start | stop } " exit 1 esac solaris10 # chmod 755 banner.ksh
3. 위치 인자(positional parameter)의 이해 pp 변수명 의 미 $0 셸 스크립트 이름 $1 스크립트 이름 다음의 첫 번째 인자 $2 두 번째 인자 $3~$9 세 번째부터 여덟 번째 인자 ${10}~${N} 열 번째 인자, N의 값에 표시하고자 하는 인자값을 넣는다. $* 모든 인자 $@ $# 인자의 총 개수
solaris10 # vi pp.ksh #!/bin/ksh echo "Script name : $0 " echo "first argument : $1 " echo "second argument : $2 " echo "third argument : $3 " echo "fourth argument : $4 " echo "fifth argument : $5 " echo "sixth argument : $6 " echo "seventh argument : $7 " echo "eighth argument : $8 " echo "ninth argument : $9 " echo "tenth argument : ${10} " echo "All argument : $* " echo "All argument : $@ " echo "Number of all argument : $# “ solaris10 # chmod 755 pp.ksh solaris10 # ./pp.ksh a b c d e f g h i j
본쉘 스타일 solaris10 # cat /etc/init.d/volmgt #!/sbin/sh # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # ident "@(#)volmgt 1.9 SMI" case "$1" in 'start') if [ -f /etc/vold.conf -a -f /usr/sbin/vold -a \ "${_INIT_ZONENAME:=`/sbin/zonename`}" = "global" ]; then echo 'volume management starting.' svcadm enable svc:/system/filesystem/volfs:default fi ;; 'stop') svcadm disable svc:/system/filesystem/volfs:default *) echo "Usage: $0 { start | stop }" exit 1 esac exit 0
/etc/init.d/volmgt 를 콘셸 스타일로 변경 #!/bin/ksh # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # ident "@(#)volmgt 1.9 SMI" case "$1" in 'start') if [[ -f /etc/vold.conf && -f /usr/sbin/vold && \ "${_INIT_ZONENAME:=`/sbin/zonename`}" = "global" ]]; then echo 'volume management starting.' svcadm enable svc:/system/filesystem/volfs:default fi ;; 'stop') svcadm disable svc:/system/filesystem/volfs:default *) echo "Usage: $0 { start | stop }" exit 1 esac exit 0
5. 제어문의 반복구조 ( for, while ) for 구문 리스트(list)로 올 수 있는 형태 첫 번째 - 직접 값을 나열 한다. 예를 들어 1 2 3 4 5 6 7 8 9 를 나열한다. 두 번째 - 백쿼트(` `) 안에 명령어를 입력해 그 결과들을 리스트로 사용한다. 세 번째 - 애스터리스크(*)를 사용해 파일명을 대체 한다. 네 번째 – 변수 명을 사용해 변수 값을 리스트로 사용할 수 있다. for 변수 in 리스트(list) # 리스트는 여러 개의 값이 올 수 있다. do # do 와 done 사이에는 리스트에 있는 값들이 다 처리 될 실행할 명령어 # 때까지 실행할 명령어를 넣는다. done
/etc/rc3 파일 발췌 01 if [ -d /etc/rc3.d ]; then 02 for f in /etc/rc3.d/K*; do 03 if [ -s $f ]; then 04 case $f in 05 *.sh) /lib/svc/bin/lsvcrun -s $f stop ;; 06 *) /lib/svc/bin/lsvcrun $f stop ;; 07 esac 08 fi 09 done 10 11 for f in /etc/rc3.d/S*; do 12 if [ -s $f ]; then 13 case $f in 14 *.sh) /lib/svc/bin/lsvcrun -s $f start ;; 15 *) /lib/svc/bin/lsvcrun $f start ;; 16 esac 17 fi 18 done 19 fi
while 구문 while 조건식 do 실행할 명령어 done
solaris10 # vi adduser.ksh #!/bin/ksh i=1 while (( i <= 100 )) do if [[ ! -e /home1 ]] ; then mkdir /home1 fi /usr/sbin/useradd -d /home1/user$i -m -s /bin/ksh user$i /bin/echo " adding user : user$i “ /usr/bin/passwd -d user$i (( i = i + 1 )) done solaris10 # chmod 755 adduser.ksh solaris10 # ./adduser.ksh
while로 메뉴 만들기 결과 화면 ***** 프로그램을 선택하시오 **** 1. 프로세스 관리 2. 사용자 관리 3. CRON 관리 4. 백업 관리 q. 프로그램 종료 메뉴를 선택하시오 ?
solaris10 # vi program.ksh #!/bin/ksh clear while true do echo "***** 프로그램을 선택하시오 **** 1. 프로세스 관리 2. 사용자 관리 3. CRON 관리 4. 백업 관리 q. 프로그램 종료 메뉴를 선택하시오? \c " read PROGRAM
case "$PROGRAM" in 1) process_mgt.ksh ;; 2) user_mgt.ksh 3) cron_mgt.ksh 4) backup_mgt.ksh q) echo " Program Exit " exit 0 esac done solaris10 # chmod 755 program.ksh
6. 함수의 활용 # 함수명 정의부 함수명() { 스크립트 내용 셸 함수 정의 및 호출 } #스크립트 본문 함수명 # 함수 호출
함수테스트 #!/bin/ksh ftest() { for i in 1 2 3 4 5 6 7 8 9 do A=$(( $DAN * $i )) echo "$DAN * $i = $A“ done } echo “단을 입력하시오? \c" read DAN
while true do echo ftest $DAN echo “단을 입력하시오? \c" read DAN done
solaris10 # vi shell_08.ksh #!/bin/ksh # network interface instance # which_inst() 함수 정의부 which_inst () { case "$1" in hme*) echo $1 | sed 's/hme//' ;; qfe*) echo $1 | sed 's/qfe//' ;; vmxnet*) echo $1 | sed 's/vmxnet//' ;; esac }
# print_link() 함수 정의부 print_link() { LINK_STATUS=`/usr/sbin/ndd /dev/$1 link_status` > /dev/null 2>&1 LINK_SPEED=`/usr/sbin/ndd /dev/$1 link_speed` > /dev/null 2>&1 LINK_MODE=`/usr/sbin/ndd /dev/$1 link_mode` > /dev/null 2>&1 case "$1" in hme* | qfe* ) print if [[ $LINK_STATUS = 1 ]]; then echo "Link Status is up" else echo "Link Status is down" fi if [[ $LINK_SPEED = 1 ]]; then echo "Link Speed is 100Mbps" else echo "Link Speed is 10Mbps" if [[ $LINK_MODE = 1 ]]; then echo "Link Mode is Full Duplex" else echo "Link Mode is Half Duplex" ;; esac }
clear while true do print print -n ". 네트워크 관리 프로그램 clear while true do print print -n "***** 네트워크 관리 프로그램 ***** 1) 네트워크 카드 보기 2) 네트워크 카드별 Duplex 보기 q) 프로그램 종료(Enter) 메뉴를 선택하세요 ( 1,2,q) ? " read NET case "$NET" in 1) /usr/sbin/ifconfig -a print -n "아무키나 누르시오 " read KEY ;;
2) print print -n "네트워크 카드를 선택하시오 ? " read NETCARD INST=`which_inst ${NETCARD}` # which_inst() 함수 호출 case "$NETCARD" in hme*) DEV=hme /usr/sbin/ndd -set /dev/${DEV} instance ${INST} print_link ${DEV} # print_link() 함수 호출. ;; qfe*) DEV=qfe print_link ${DEV} # print_link() 함수 호출. vmxnet*) DEV=vmxnet print_link ${DEV} # print_link() 함수 호출. esac print -n "아무키나 누르시오 " read KEY
q|"") print print "프로그램을 종료합니다. " exit 2 ;; esac done solaris10 # chmod 755 shell_08.ksh solaris10 # ./shell_08.ksh