본문 바로가기

Academy I/Tech Academy

Advanced Bash-Scripting - 예제

아주 간단한 쉘 프로그램을 만들것이다. 이 프로그램은 몇 개의 시스템 명령어들을 포함하고 있는데, 파일의 내용을 모두 삭제하는 일을 한다.
# Log 파일의 내용을 깨끗하게 지운다. 
# Root 권한으로 실행해야 한다.

cd /var/log
cat /dev/null > message
cat /dev/null > wtmp
echo "Log files cleaned up"
이 프로그램은 줄 단위로 명령을 차례 차례 실행하는 일을 한다. 말그대로 batch 프로그램인 셈인데, 명령어의 집합이기 때문에 전문 프로그래머가 아니라도 쉽게 수정할 수 있다. 물론 시스템 명령어들이 어떤일을 하는지에 대한 정도는 알고 있어야 한다. cat이 어떤일을 하는 시스템 명령어인지 /dev/null은 뭔지 ">"가 어떤 의미인지 하는 것들을 알아야 한다.

위 쉘 프로그램을 좀 더 프로그램답게 수정했다.
#!/bin/bash
# Proper header for a Bash script.

# Cleanup, version 2

# Root 권한으로 실행해야 한다. 

# 하드코딩 보다는 변수를 사용하는게 낫다.
LOG_DIR=/var/log
cd $LOG_DIR

cat /dev/null > messages
cat /dev/null > wtmp


echo "Logs cleaned up."

더 복잡한 프로그램이다. 정말 프로그램 느낌이 난다.
#!/bin/bash
# Cleanup, version 3

#  Warning:
#  -------
#  This script uses quite a number of features that will be explained
#+ later on.
#  By the time you've finished the first half of the book,
#+ there should be nothing mysterious about it.


LOG_DIR=/var/log # LOG 파일이 있는 디렉토리
ROOT_UID=0     # 이 스크립트는 단지 root 유저(UID가 0)만 사용할 수 있다. 
LINES=50       # 저장할 줄 수 
E_XCD=86       # Can't change directory?
E_NOTROOT=87   # Non-root exit error.


# 루트 유저가 실행하는지 검사한다. 
if [ "$UID" -ne "$ROOT_UID" ]
then
  echo "Must be root to run this script."
  exit $E_NOTROOT
fi  

if [ -n "$1" ]
# 명령행 인자를 검사한다. 
then
  lines=$1
else  
  lines=$LINES # 명령행 인자가 없다면 기본 값을 설정한다. 
fi  


cd $LOG_DIR

if [ `pwd` != "$LOG_DIR" ]  # 현재 작업 디렉토리가 $LOG_DIR 인지 확인한다.  
                            # 그렇지 않다면 종료한다.
then
  echo "Can't change to $LOG_DIR."
  exit $E_XCD
fi  # Doublecheck if in right directory before messing with log file.

tail -n $lines messages > mesg.temp # messlog 파일의 마지막 $lines 줄을 mesg.temp 파일에 저장한다.  
mv mesg.temp messages               # mesg.temp 파일을 messages 파일로 저장한다. 


cat /dev/null > wtmp  #  wtmp 파일의 내용을 지운다. 
echo "Log files cleaned up."

exit 0
# 모든 작업을 성공적으로 마쳤다면, 0을 반환한다.
# 이 반환 값을 검사해서 작업 성공 여부를 확인할 수 있다. 
이 프로그램의 첫번째 줄은 "#!"로 시작한다. 이것은 프로그램의 코드를 해석하기 위해서 어떤 프로그램을 사용해야 할지를 알려준다. "#!/bin/bash"는 bash shell 프로그램을 호출해서 코드를 해석하라는 것을 의미한다. bash뿐만 아니라 다양한 프로그램을 해석기로 사용할 수 있다.
#!/bin/sh
#!/bin/bash
#!/usr/bin/perl
#!/usr/bin/tcl
#!/usr/bin/python
#!/bin/sed -f
#!/bin/awk -f

#!/bin/sh 는 표준 Bourn shell 프로그램으로 리눅스 뿐만 아니라 다른 모든 유닉스에서도 사용할 수 있다. 만약 다른 유닉스에서도 호환되는 쉘 프로그램을 만들기를 원한다면 /bin/bash 대신에 /bin/sh 를 사용해야 한다. bash와 sh는 비슷하지만 완전히 호환되지 않기 때문에, sh를 해석기로 사용할 경우 코드 작성에 주의를 기울여야 한다.

다른 유닉스 운영체제로의 호환을 염두에 두지 않는다면 "/bin/bash"를 사용하면 된다. 리눅스는 bash가 표준 쉘이며, /bin/sh는 bash의 링크다. bash는 sh를 개선했기 때문에 sh 보다는 좀 더 많은 언어적 기능을 지원한다. 특별한 이유가 없다면 bash를 사용하면 된다. 다른 유닉스를 대상으로 할 경우 sh용의 프로그램을 만드는 것보다는 해당 유닉스용 bash를 설치하는걸 권장한다. 대부분의 유닉스가 bash 패키지를 제공한다.


[출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Bash/AdvancedBashScripting]/Chapter02