반응형

필자 서문


프로그래머들은 솔라리스 제품을 사용하기 시작할 때 프로그래밍 스크립트를 즉시 시작하기를 원합니다. 처음에는 효율성과 간결성에 대해서는 관심들이 없고 오로지 그 결과에만 관심을 가지고 있습니다. 본 기술 자료에서는 신속한 시작을 위해 검증된 쉘 프로그래밍 기법에 대해 설명합니다. 경험이 쌓일수록 자신만의 프로그래밍 스타일을 개발하고 스크립트의 효율성과 간결성을 향상시킬 수 있을 것입니다.

배경


command shell 은 사용자와 상호 작용하고 운영 시스템과 통신하는 레이어입니다 MS-DOS를 사용할 때 대부분의 사람들은 command.com 쉘을 사용하지만, COMSPEC 환경 변수를 통해 다른 쉘이 지정될 수도 있습니다.

이와 유사하게, 각 UNIX 사용자는 UNIX로 전달하기 위해 사용할 명령 쉘을 선택해야 합니다. UNIX 계정이 설정될 때 시스템 관리자는 사용자의 기본 쉘을 선택합니다. 표준 옵션은 Bourne Shell(/bin/sh), C-Shell(/bin/csh), Korn Shell(/bin/ksh), Bourne-Again Shell(/bin/bash)입니다. 많은 개발자들이 C와 유사한 구문 때문에 C-쉘을 사용하지만 이는 주관적인 선택이며, 여기에서는 Korn 쉘만을로 사용합니다. 다른 쉘에서는 구문이 세대로 실행되지 않을 수도 있습니다.

명령행에서 쉘 스크립트를 실행하면 기본 쉘이 사용됩니다. 기본 쉘이 Korn이라면 기술 자료에 있는 스크립트는 구문 오류 없이 실행됩니다. 하지만 스크립트를 실행하기 위해 다른 쉘을 원한다면 어떻게 해야 할까요? 스크립트가 항상 Korn 쉘을 사용해 실행되도록 하려면 사용자의 기본 쉘에만 의존할 수 없습니다. 해결책은 스크립트의 첫 행에 스크립트가 어느 쉘 아래에서 실행될지 표시되는 UNIX 기능을 사용하는 것입니다. 코드 예제 1의 구문은 현재 사용자가 어느 쉘을 사용하든 상관없이 스크립트가 Korn 쉘을 사용해 실행되도록 지시합니다.

#!/bin/ksh

# your script goes here. All lines starting with # 
# are treated as comments
코드 예제 1 - 스크립트가 Korn 쉘에 의해 실행되도록 지정합니다.

일부 문서에서는 표 1에 나타난 것처럼 현재 쉘을 표시하기 위해 다른 명령 프롬프트 기호를 사용합니다. (필자가 가장 선호하는 쉘이 Korn 쉘이기 때문에 본 기술 자료에 나오는 모든 예제는 $-prompt를 사용합니다.) 스크립트가 항상 Korn 쉘을 사용하여 실행되도록 할 수 없기 때문에 각 스크립트의 첫 행으로 #!/bin/ksh를 입력합니다. (본 기술 자료의 $-prompt는 단지 명령이 명령행에 입력되고 있음을 나타냅니다.)

프롬프트 쉘l
$ Bourne 또는 Korn 쉘
% C-shell
# Root login

표 1 - UNIX 프롬프트 기호

스크립트 작성 - 기초


UNIX 스크립트 파일은 DOS BAT 파일과 유사합니다. DOS에서의 프로그래밍 권장 사항과 비권장 사항은 모두 UNIX에도 적용됩니다.

스트립트 작성과 관련된 단계는 다음과 같습니다:

  1. 쉘 프롬프트에서 UNIX 명령을 대화식으로 실행합니다.
  2. UNIX 명령을 포함하는 쉘 스크립트를 작성합니다.
  3. 쉘 스크립트를 실행 가능하도록 만듭니다.
  4. 스크립트를 테스트합니다.
  5. 스크립트를 실행합니다.
    1. 대화식으로
    2. 미래의 어느 일자 및 시간에 단 한 번
    3. 고정된 일정에 따라 반복적으로
    4. HTML 형식 사용

간단한 스크립트 작성


vmstat 정보를 확보하기 위한 스크립트를 작성하고자 한다고 가정해 보십시오. 1분 동안 2초 간격으로 vmstat를 실행하고자 합니다. 위에 설명된 5단계를 사용해 목표를 달성할 수 있습니다.

먼저, man vmstat를 사용해 vmstat에 대한 문서를 조회합니다. 그 다음, 명령을 대화식으로 실행해 구문과 예상되는 출력을 파악합니다. 코드 예제 2는 vmstat를 2초 간격으로 30회 실행하는 구문을 보여줍니다.

$  vmstat  2  30
코드 예제 2 - vmstat 명령을 2초 간격으로 30회 대화식으로 실행

쉘 스크립트 작성


다음으로, 명령을 포함하는 스크립트 파일을 작성합니다. 스크립트 위치와 스크립트 이름을 설명하는 표준을 확립해야 합니다. 예를 들어 회사와 같은 특정 카테고리의 모든 사항을 /usr/local 아래의 하위 디렉토리에 저장합니다. 이 예제에서는 회사를 Acme Products로 가정하므로 디렉토리는 /usr/local/acme입니다. 이 디렉토리 내에 scripts라는 하위 디렉토리와 logs라는 하위 디렉토리를 만드십시오. 목적에 따라 다른 하위 디렉토리가 필요할 수도 있습니다.

다음으로, vi와 같은 텍스트 편집기를 사용해 capture_vmstat.sh라는 스크립트 파일을 작성합니다. EXE, COM, BAT가 실행 가능한 파일을 나타내는 DOS와 달리, UNIX에서는 파일 확장자의 의미가 없습니다. .sh를 확장자로 사용해 쉘 스크립트 파일을 표시할 수 있지만 스크립트를 실행 가능하도록 만들지는 못합니다. 파일에 대한 이 명명 규칙을 통해 보다 쉽고 신속하게 파일을 식별할 수 있습니다. 또한, 파일 이름이 표준을 준수한다면 find 명령을 사용해 특정 유형의 모든 파일을 찾을 수 있습니다.

스크립트 파일은 두 개의 행을 보유합니다. 첫 번째 행은 일말의 여지를 두지 않고 Korn 쉘이 이 스크립트에 있는 명령을 실행하도록 지정합니다. 두 번째 행은 UNIX 명령 그 자체입니다. 코드 예제 3은 capture_vmstat.sh 스크립트의 전체 목록입니다.

#!/bin/ksh

vmstat  2  30
코드 예제 3 - vmstat를 2초 간격으로 30회 실행하는 capture_vmstat.sh 스크립트

쉘 스크립트를 실행 가능하도록 만들기


파일 확장자를 이용해 파일의 실행 가능성 여부를 판단하는 DOS와 달리, UNIX는 파일 접근 권한(file permission)에 의존합니다. chmod 명령은 파일을 실행 가능으로 표시하는 데 사용됩니다.

execute-bit를 설정하는 가장 간단한 방법은 chmod +x capture_vmstat.sh를 사용하는 것입니다. 현업 환경에서는 공개된 서버에서 스크립트에 대한 전체 액세스를 제어하기 위해 소유자, 그룹 및 세계 권한(world permission)을 고려해야 합니다. (파일 접근 권한 주제는 본 문서의 범위를 벗어납니다.) 보다 자세한 정보는 man chmod를 참조하십시오.

쉘 스크립트 테스트


이제 스크립트를 테스트할 준비가 되었습니다. DOS와 달리, UNIX는 실행할 파일을 현재 디렉토리에서 자동으로 찾지 않습니다. UNIX는 PATH 환경 변수를 제공하며 단지 PATH 변수에서 확인된 디렉토리에서 실행 파일을 검색합니다. 대부분의 사람들이 PATH에 현재 디렉토리를 포함시키지 않아(점이 현재 디렉토리를 나타냄) /usr/local/acme/scripts가 PATH에 존재하지 않기 때문에 코드 예제 4의 명령을 입력하는 것만으로는 실행되지 않습니다.

$  cd /usr/local/acme/scripts

$  capture_vmstat.sh
코드 예제 4 - "."이 PATH에 없으면 스크립트가 실행되지 않습니다

경로를 포함하여 스크립트의 전체 파일명을 명시적으로 지정해야 합니다. 나중에 변경되거나 둘 중 하나가 잘못될 가능성이 있으므로 PATH 변수에 의존하지 마십시오. 우선, 스크립트가 있던 디렉토리가 실수로 PATH에서 제거될 수 있으며 이 경우 UNIX는 더 이상 스크립트를 찾지 못할 것입니다. 심지어 UNIX는 새로운 PATH에 있는 다른 디렉토리에서 동일한 이름을 가진 스크립트를 찾아 실행할 수도 있습니다. 그러므로 안전을 위해서는 코드 예제 5에서처럼 전체 파일명을 지정하여 스크립트를 실행해야 합니다.

$  /usr/local/acme/scripts/capture_vmstat.sh
코드 예제 5 - UNIX가 올바른 스크립트를 찾을 수 있도록 전체 파일명 지정

일일이 입력하기가 번거로우므로 "."(점)이 현재 디렉토리를 나타낸다고 가정합니다. 우선, 스크립트 디렉토리로 변경한 다음 코드 예제 6에서처럼 스크립트명에 "./"(점-슬래시)를 덧붙여 스크립트를 실행합니다. 스크립트 하나만 실행하는 경우에는 별 차이가 없지만 스크립트 디렉토리에서 여러 개의 스크립트를 실행하는 경우에는 디렉토리명을 한 번만 입력하면 되는 장점이 있습니다.

$  cd /usr/local/acme/scripts

$  ./capture_vmstat.sh
코드 예제 6 - 점-슬래시(./) 표기를 사용해 스크립트 실행

capture_vmstat.sh 스크립트를 어떤 방법으로 호출하든 간에, vmstat를 대화식으로 실행할 때 얻은 결과와 출력이 동일해야 합니다.

스크립트 실행


이제 스크립트가 작성되었고 그 작동 방식을 알고 있습니다. 스크립트를 다음 네 가지 방법으로 실행할 수 있습니다:

1.대화식


스크립트를 문서화하여 다른 사람(헬프 데스크 직원 등)이 스크립트 파일을 실행할 수 있도록 합니다. DOS 사용자가 그들을 위해 만들어진 BAT 파일을 사용하기 위해 DOS 명령이나 구문을 이해할 필요가 없는 것과 매한가지로, 스크립트를 실행하는 사람들이 UNIX 명령이나 구문을 알아야 할 필요는 없습니다.

2.at 명령 사용


at 명령을 사용해 향후 언젠가 한번 스크립트를 실행합니다. 자세한 내용은 man at을 확인하십시오. 일부 UNIX 시스템은 사용자가 로그아웃하면 at-jobs 실행을 취소합니다. 시스템 문서를 신중하게 확인합니다.

3.cron 유틸리티 사용


crontab 파일을 사용해 고정된 일정에 따라 스크립트를 반복적으로 실행합니다. 자세한 내용은 man crontab을 확인합니다. 코드 예제 7은 월/수/금요일마다 오전 8시-오후 5시까지 한 시간에 한번 X시 10분에 스크립트를 실행하는 간단한 crontab 입력을 보여줍니다:

10   8-17   *   *  1,3,5  /usr/local/acme/scripts/capture_vmstat.sh
코드 예제 7 - capture_vmstat.sh를 실행하는 crontab 입력 script

스크립트를 실행하기 위한 네 번째 방법으로 넘어가기 전에, crontab을 통해 스크립트를 실행할 경우 생기는 두 가지 문제를 이해해야 합니다. 첫째, 스크립트가 실행될 때 로그인하지 않았기 때문에 기본 쉘이 되는 Korn 쉘에 의존할 수 없습니다. 그러므로, 코드 예제 1에 설명된 것처럼 #!/bin/ksh를 스크립트의 첫 행으로 사용하도록 해야 합니다. 둘째, 현재 버전의 스크립트는 터미널로 출력을 전송합니다. cron이 스크립트를 실행할 때 터미널이 없으므로, cron은 stdout의 경로를 다른 곳으로 재지정해야 합니다. 정상적인 위치는 crontab으로 스크립트를 실행한 사용자의 e-메일 수신함(inbasket)입니다. 이 방법도 괜찮지만, 기본 스크립트를 확장할 때 아래에 설명된 다른(더 나은) 해결책을 사용할 수 있습니다.

4.HTML 형식 사용


HTML 형식을 사용해 스크립트를 실행하고 CGI(common gateway interface)를 통해 스크립트를 게시합니다. 명령의 출력은 브라우저로 다시 전송되므로 <PRE>와 </PRE> HTML 태그는 서식을 보존하는 데 사용되어야 합니다.

이 HTML 형식 메소드는 여기서 설명한 것보다 많으며, FORM과 CGI를 사용할 경우 수많은 보안 위험이 존재합니다. 그러나, 이 메소드는 사내 헬프 데스크 직원이나 기타 레벨1 지원 인력이 사용하기에 매우 성공적인 것으로 입증되었습니다.

간단한 스크립트 확장


이전 스크립트는 새로운 프로그래밍 언어를 배울 때 작성되는 최초의 표준 프로그램인 "hello, world"의 쉘 스크립트 버전이었습니다. 이제 몇 가지 기본 기능을 여기에 추가할 수 있습니다.

stdout 경로 재지정


먼저, 스크립트는 출력을 stdout으로 전송합니다(정상적으로는 터미널임). 스크립트를 확장해 코드 예제 8에서처럼 출력 경로를 로그 파일로 재지정할 수 있습니다.

#!/bin/ksh

vmstat  2  30  >  /usr/local/acme/logs/vmstat.log
코드 예제 8 - stdout 경로를 파일로 재지정

그러나 이로 인해 몇 가지 새로운 문제가 발생합니다. 우선, 스크립트를 실행할 때마다 마지막 로그 파일의 내용을 덮어쓰게 됩니다.+ 이 문제를 해결하려면 기존 로그 파일의 끝에 새로운 출력을 덧붙입니다. 파일에 있는 date-time stamp는 마지막 로그가 작성된 시점만을 표시하므로 이제 로그에 있는 각 출력이 작성된 시점을 알아야 합니다.

스크립트 내 하위 명령 실행

스크립트의 각 실행보다 앞서는 파일에 현재의 일자와 시간을 기록합니다. 기존 파일을 덮어쓰는 대신 >>를 사용해 파일 끝에 출력을 덧붙입니다. 코드 예제 9에서, find 및 find-next를 사용해 파일을 검사하기 쉽도록 독립적으로 파악할 수 있는 문자를 열 1에 놓습니다. 또한 로그 파일에 현재의 일자와 시간을 기록할 수도 있습니다. 코드 예제 9 $(date)는 Korn 쉘이 date 명령을 실행하고 출력을 echo 명령행으로 배치하도록 지시합니다. UNIX 명령을 실행하고 출력을 사용하려고 할 때마다 $를 입력하고 괄호 안에 명령을 넣으십시오.

#!/bin/ksh

echo "#--- $(date)"  >> /usr/local/acme/logs/vmstat.log

vmstat  2  30	>> /usr/local/acme/logs/vmstat.log
코드 예제 9 - 로그 파일에 stdout 추가

코드 예제 10에서 Korn 쉘은 netstat 명령, grep for ESTABLISH를 실행하고, 이들 명령을 $(xxx) 안에 넣어 행 수를 세는 데 wc를 사용하도록 지정될 수 있습니다. 나아가 Korn 쉘은 이러한 명령의 출력을 환경 변수 CTR_ESTAB에 저장하도록 지시됩니다. 그 다음, echo 명령에서 Korn 쉘은 해당 환경 변수에 저장된 값을 사용하도록 지시됩니다. 환경 변수에 저장된 값을 사용하려면 변수 이름 앞에 $를 넣습니다(예: $CTR_ESTAB). 가독성을 높이고 모호성을 방지하려면 중괄호 안에 변수 이름을 넣는 Korn 쉘 옵션을 사용합니다(예: ${CTR_ESTAB}).

# store current date as YYYYMMDD in variable DATE for later 
# use

export DATE=$(date +m%d)

# count number of established socket connections and write. 
# to log

export CTR_ESTAB=$(netstat -na -P tcp | grep ESTABLISH | wc 
  -l)

export CTR_CLOSE_WAIT=$(netstat -na -P tcp | grep CLOSE WAIT 
  | wc -l)

echo "${DATE} ${CTR_ESTAB} ${CTR_CLOSE_WAIT} >> ${LOG_FILE}
코드 예제 10 - $(xxx)를 사용해 Korn 쉘 스크립트 내 명령 실행

고유 파일명 생성


여러 사용자가 스크립트를 동시에 실행하면 어떤 일이 발생할까요? 스크립트의 각 인스턴스는 동일한 출력 파일에 기록할 것이므로, 각 스크립트의 출력은 출력 파일에 인터리브됩니다. 코드 예제 11에서처럼 파일 이름에 PID 번호($$로 표현)를 넣어 고유한 출력 파일명을 작성할 수 있습니다.

#!/bin/ksh

echo "#--- $(date)" 
  >> /usr/local/acme/logs/vmstat.$$.log

vmstat  2  30	>> /usr/local/acme/logs/vmstat.$$.log
코드 예제 11 - $$를 사용해 현재 PID를 사용하는 고유한 파일명 생성

다음 사용자가 스크립트를 실행할 때 다른 PID가 스크립트 실행에 할당되기 때문에 기존 로그 파일에 추가되는 것이 아니라 매번 별도의 로그 파일을 작성하게 됩니다 잘못된 것은 아니지만 이런 결과를 원하지도 않았습니다.

스크립트가 실행될 때마다 값이 변경되는 환경 변수를 사용하는 대신 스크립트 실행 이전에 스크립트 외부에서 한 번 설정된 환경 변수를 사용하는 방법도 생각해볼 수 있습니다. UNIX는 사용자가 로그인할 때마다 LOGNAME 환경 변수를 설정합니다. 코드 예제 12에서, 이 값은 각 사용자가 로그 파일을 가질 수 있도록 로그 파일명에 들어갑니다:

#!/bin/ksh

echo "#--- $(date)"	
  >> /usr/local/acme/logs/vmstat.${LOGNAME}.log

vmstat  2  30		
  >> /usr/local/acme/logs/vmstat.${LOGNAME}.log
코드 예제 12 - 값이 외부에서 설정된 환경 변수를 사용해 파일명 생성

구조적 프로그래밍 기법


두 번의 최종 마무리 점검을 거쳐 기본 Korn 쉘 스크립트를 완료합니다. 첫째, vmstat 명령의 빈도 또는 기간을 변경하고자 하는 경우 어떻게 될까요? vmstat 명령의 간격과 기간을 하드 코딩(hard-coding)하는 대신 명령행 인수를 사용해 해당 값을 받아들일 수 있습니다. 이러한 인수는 vmstat 명령이 인수를 액세스할 수 있는 환경 변수에 저장될 수 있습니다. 물론, 사용자가 명령행을 사용해 값을 제공하지 않는 경우 스크립트는 기본값을 제공해야 합니다.

둘째, 로그 파일 명명 규칙에 대한 생각을 변경하면 어떻게 됩니까? 명명 규칙은 사용자에게 명령행 인수를 사용할 때마다 제공할 것을 요구하는 사항이 아닙니다. 그러나, 스크립트의 여러 행에 하드 코딩된 로그 파일명이 있을 경우 다른 명명 규칙을 사용하기로 결정하면 이름이 지정된 위치를 확인하기 위해 스크립트의 모든 행을 검색해야 합니다.

그 대신, 환경 변수에 로그 파일명을 저장하고 변수에 포함된 파일명에 출력을 덧붙이도록 각 명령을 수정하십시오. 그러면 로그 파일 명명 규칙을 변경할 때 환경 변수가 설정된 한 행을 수정하기만 하면 됩니다.

#!/bin/ksh
# ----------------------------------------------------
# capture_vmstat.sh	<INTERVAL> <COUNT>
#	<INTERVAL> vmstat interval
#	<COUNT>	vmstat count
# run vmstat and capture output to a log file
#-----------------------------------------------------

# indicate defaults for how often and for how long 
# to run vmstat
export INTERVAL=2		# every 2 seconds
export COUNT=30		# do it 30 times

# obtain command line arguments, if present
if [ "${1}" != "" ]
then
	INTERVAL=${1}
	# if there is one command line argument, 
	# maybe there's two
	if [ "${2}" != "" ]
	then
	COUNT=${2}
	fi
fi

# directories where scripts and logs are stored
export PROGDIR=/usr/local/acme/scripts
export LOGDIR=/usr/local/acme/logs

# define logfile name and location
export LOG_FILE=${LOGDIR}/capture_vmstat.${LOGNAME}.log

# write current date/time to log file
echo "#--- $(date)"		>> ${LOG_FILE}
vmstat  ${INTERVAL}  ${COUNT}	>> ${LOG_FILE}

# say goodnight, Gracie
exit 0
코드 예제 13 - capture_vmstat.sh 스크립트의 더욱 강력한 버전

for-loop 스크립트 작성


객체 목록에 대해 단일 명령을 실행하고자 하는 경우가 있습니다. 예를 들어, rsh 명령을 사용해 여러 서버에 대해 동일한 명령을 원격으로 실행하려 할 수도 있습니다(자세한 내용과 r-명령을 사용할 때의 보안 위험에 대해서는 man rsh를 참조합니다). .

한 가지 기법은 환경 변수에 LIST라고 하는 객체 목록을 저장하는 것입니다. 그러면 for loop를 사용해 rsh 명령을 반복적으로 실행할 수 있으며, 각 루프는 LIST에 다음 값을 보유하게 됩니다. 코드 예제 14는 for-loop 스크립트 샘플을 보여줍니다.

#!/bin/ksh

export LIST="bvapp1 bvapp2 bvapp3"

export LOG=/usr/local/acme/logs/throw_away.log

for SERVER in ${LIST}
do
  # each loop has a different value for ${SERVER}
  echo "#------- values from ${SERVER}" >> ${LOG}
  rsh  ${SERVER} 
  "ps -f -u bv -o pid,pmem,pcpu,rss,vsz" >> ${LOG}
done

# say goodnight, Gracie
exit 0
코드 예제 14 - 간단한 for-loop 스크립트

while-loop 스크립트 작성


경우에 따라 단일 명령을 실행하고 잠시 기다린 다음 명령을 다시 실행하기를 원할 수도 있습니다. 때로는 이 루프가 무제한 계속되기를 원할 수도 있고 때로는 루프가 한정된 횟수 만큼 실행된 다음 종료되기를 원합니다.

사용자 bv 아래에서 실행되는 프로세스를 모니터링하려고 하며 2시간 동안 10분마다 bv를 모니터링하기를 원한다고 가정해 보겠습니다. 우선, 코드 예제 15에 나오는 코드를 사용해 명령을 대화식으로 테스트합니다(자세한 내용은 man ps를 참조합니다):

ps  -f -u bv  -o  pid,pcpu,pmem,rss,vsz,comm
코드 예제 15 - -o 인수를 사용하는 대화식 ps 명령

이제 이 명령을 루프에서 실행하는 스크립트 파일을 작성해야 합니다. 루프는 ps 명령 실행 간의 10초 동안 일시 정지하고 720회 실행해야 합니다[2시간 동안 10초마다 한번, 즉 분당 6회 또는 시간당 360회(60분/시 * 6/분)]. 코드 예제 16은 간단한 while-loop 스크립트를 보여줍니다.

#!/bin/ksh

export INTERVAL=10
export COUNT=720

export LOG=/usr/local/acme/logs/while_loop_test.log

export CTR=0
while [ true ]
do
	if [ ${CTR} -ge ${COUNT} ]
	then
		exit
	fi
	echo "#------- $(date +m%d-03/24/03M%S)"	
          >> ${LOG}
	ps  -f  -u  bv  -o  pid,pcpu,pmem,rss,vsz,comm	
          >> ${LOG}
	CTR=$(expr ${CTR} + 1)
	sleep ${INTERVAL}
done
코드 예제 16 - 간단한 while-loop 스크립트

코드 예제 17은 출력 로그 파일의 일부분을 보여줍니다.

#------- 19991203-123237
  PID %CPU %MEM  RSS  VSZ COMMAND
12007  0.2  0.8 13640 24280 cmsdb
11938  0.0  0.7 11536 20496 sched_poll_d
<snip>
#------- 19991203-123240
  PID %CPU %MEM  RSS  VSZ COMMAND
12007  0.2  0.8 13640 24280 cmsdb
11938  0.0  0.7 11536 20496 sched_poll_d
<snip>
#------- 19991203-123243
  PID %CPU %MEM  RSS  VSZ COMMAND
12007  0.3  0.8 13640 24280 cmsdb
11938  0.0  0.7 11536 20496 sched_poll_d
<snip>
#------- 19991203-123246
<and-so-on>
코드 예제 17 - while-loop 스크립트의 출력

퀵 레퍼런스 카드(Quick Reference Card)


아래 프로그래밍 팁과 기법은 본 기술 자료에 제시된 프로그래밍 스타일과 방법론에 대한 퀵 레퍼런스로서 여기에서 다룬 주제에 대한 퀵 레퍼런스 버전을 확인할 수 있을 것입니다.

1. 항상 다음과 같은 행으로 스크립트를 시작합니다


#!/bin/ksh

2. 항상 변수를 정의할 때 대문자를 사용합니다. 소문자를 사용해 단어를 분리합니다.


BIN_DIR=/opt/bv1to1/bin

3. 하위 프로세스가 값을 자동으로 액세스하도록 항상 환경 변수를 익스포트합니다:


export SUPPORT_IDS="userA@domain.com,userB@domain.com

4. UNIX 명령을 실행하고 Korn 쉘 스크립트의 어딘가에 출력을 사용하려면 $를 입력하고 괄호 안에 명령을 넣은 다음 출력을 환경 변수에 저장합니다.


export CTR_ESTAB=$(netstat -na | grep ESTABLISH | wc -l)

5. 환경 변수에 저장된 값을 사용하려면 변수명 앞에 $를 넣습니다. 가독성을 높이고 모호성을 방지하려면 중괄호 안에 변수 이름을 넣습니다.


echo "The number of ESTABLISHED connections is ${CTR_ESTAB}"

6. 고유한 파일명을 갖게 하려면 $$를 사용해 파일명에 PID 번호를 포함시킵니다. 파일 확장자 바로 앞의 파일명에 PID 번호를 삽입합니다:


export LOG_FILE=/tmp/capture_vmstat.$$.log

7. chmod +x 파일명을 사용해 스크립트 파일을 실행 가능하도록 만듭니다.


chmod  +x  capture_vmstat.sh

8. 스크립트가 현재 디렉토리에 있다는 것을 UNIX가 알 수 있도록 스크립트 이름 앞에 점-슬래시(./)를 넣습니다.


./capture_vmstat.sh

9. stdout ( > )의 경로를 로그 파일로 재지정하거나 stdout ( >> )을 로그 파일에 덧붙입니다.


./capture_vmstat.sh >> ${LOG_FILE}

10. stderr의 경로를 stdout과 동일한 대상 또는 고유한 파일로 재지정합니다.


./capture_vmstat.sh  >> ${LOG_FILE}  2>&1

- or -

./capture_vmstat.sh  >> ${LOG_FILE}  2>>${ERR_LOG}

11. for-loop를 사용해 목록을 처리합니다.


export LIST=$(ls *sh)
for FILE in ${LIST}
do
	echo "Processing ${FILE}"
	cat ${FILE} | mailx -s "Here is ${FILE}" 
          userA@domain.com
done

Use the while-loop to process the same command 
  repeatedly.
export INTERVAL=20
export COUNT=180

export CTR=0
while [ true ]
do
if [ ${CTR} -ge ${COUNT} ]
	then
		exit
	fi
	# --- do some command here ---
	sleep ${INTERVAL}
	      CTR=$(expr ${CTR} + 1) 
done

참조 자료


UNIX Shell Programming (Hayden Books UNIX System Library)


필자: Stephen G. Kochan, Patrick H. Wood
페이퍼백 - 490페이지
2번째 개정판(1990년 1월)
Hayden Books; ISBN: 067248448X

필자 약력


켄 코트리(Ken Gottry)는 현재 NerveWire, Inc.의 수석 인프라 아키텍트로 근무하고 있으며, 메인프레임에서 데스크탑에 이르는 시스템 부문에서 30년 간 경력을 쌓았습니다. 지난 10년 동안 그는 분산, 다계층 및 웹 기반 시스템의 설계, 구현, 튜닝 업무에 전념해 왔습니다. 또한, 수많은 G2K 업체에 자문을 제공하는 성능 엔지니어로서 웹 서버, 애플리케이션 서버, Solaris상에서 실행되는 JVM을 평가하고 튜닝했습니다.

켄의 기술 자료는 썬의 개발자 웹 사이트에 게재되었던 내용이며, 최근 SysAdmin 매거진에서 Solaris 성능 튜닝에 대한 기술 자료도 발표됐습니다.

+ Recent posts