쉘기능을 자유자재로 다루기_03 HUP 시그널을 받아서 실행 중에 설정 파일을 다시 읽어들이기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: trap, uptime, .(닷 명령어) 키워드: 시그널, 끼어들기, 트랩, 리로드
사용처: 실행 중인 스크립트의 설정 파일이 바뀌어도 프로세스를 멈추지 않고 다시 설정 파일을 읽어들이고 싶을 때


실행예제

$ ./sig-hup.sh
$ kill -s HUP <프로세스 ID>  <---- 스크립트를 실행한 채로 setting.conf를 수정하고, 다른 터미널에서 시그널을 보내서 파일 출력할 곳이 변한 걸 확인

스크립트

#!/bin/sh

# 환경 초기화 셸 함수, 로그 출력할 곳을 설정한 setting.conf 읽음
loadconf() {  #----------------------------- 1
  . ./setting.conf  #----------------------- 1
}  #---------------------------------------- 1

# HUP 시그널로 설정을 다시 읽도록 정의
trap 'loadconf' HUP  #---------------------- 2

# 첫 초기화
loadconf  #--------------------------------- 3

# 무한 반복
while :  #---------------------------------- 4
do
  # uptime 명령어 결과를 setting.conf로 지정한 경로에 로그 출력
  uptime >> "${UPTIME_FILENAME}"  #--------- 5
  sleep 1
done

   

해설

이 스크립트는 서버 부하 평균값을 1초마다 한 번씩 파일로 반복 출력합니다. uptime 명령어는 다음처럼 서버 기동 시간과 서버의 과거 1분/5분/15분 부하 평균값을 출력합니다. 이 결과를 장시간 추출하면 서버 부하 상태를 볼 수 있습니다.

$ uptime
14:46:47	up 9 days, 7:18, 2 users, load averages: 1.32 1.58 1.46

이 예제에서는 셸 스크립트 프로세스에 HUP(행업) 시그널을 보내면 프로세스를 종료하지 않아도 출력용 파일을 바꿀 수 있습니다. 이런 동작은 서버에 상주하는 데몬 프로그램 등에서 자주 사용합니다.

예제를 실행하면 1에서 외부 설정 파일 setting.conf를 읽습니다. 이 setting.conf는 다음처럼 출력 파일명을 지정하는 정의 파일입니다.

  • 파일1예제에서 사용하는 설정 파일(setting.conf)

    UPTIME_FILENAME="/var/tmp/uptime.log"
    

이렇게 외부 파일을 .(닷) 명령어로 읽어 들입니다. 예제에서는 끼어들기 처리에 의해 프로세스 동작 중에 설정 파일을 다시 읽을 수 있게 됩니다. 셸 스크립트에서 끼어들기에 대응(시그널 처리)하려면 trap 명령어를 사용해야 합니다.

이 스크립트는 1에서 환경 초기화 셸 변수를 정의합니다. 현재 디렉터리 파일 setting.conf를 읽는 간단한 내용입니다. 이걸로 셸 변수 UPTIME_FILENAME이 설정되어 uptime 명령어의 로그를 출력할 곳이 정해집니다.

2는 trap 명령어로 HUP 시그널로 끼어들기를 정의한 부분입니다. 여기에서는 설정 파일을 다시 읽기 위해 loadconf 함수를 호출합니다. trap 명령어는 실제 처리를 작은 따옴표로 싸기 때문에 긴 처리는 쓰기 힘드니 셸 함수를 따로 정의해두고 그 함수를 호출하도록 하는 방법을 자주사용합니다.

설정 파일을 다시 읽는 동작에는 보통 HUP 시그널을 사용합니다. 예를 들어 웹 서버로 자주쓰는 아파치 httpd는 부모 프로세스에 HUP 시그널을 보내면 설정 파일 httpd.conf를 다시 읽어서 reload 동작을 합니다. 이러한 이유로 2에서도 HUP 시그널로 설정 파일을 다시 읽게 만들었습니다.

3은 실행했을 때 처음에 실행되는 줄입니다. 여기서 loadconf 함수를 불러서 설정을 초기화합니다. 이때 셸 변수 UPTIME_FILENAME에 “/var/tmp/uptime.log”가 설정됩니다.

4부터 실제로 uptime 명령어를 실행해서 while 반복을 합니다. while에 :(널 명령어)을 지정해서 무한 반복문으로 실행합니다.

5는 uptime 명령어 결과를 셸 변수  UPTIME_FILENAME에 출력해서 sleep 명령어로 1초 기다리고 다시 uptime 명령어를 반복합니다.

그럼 설정 파일을 바꿔 쓰고 프로세스를 실행한 채로 파일 출력할 곳을 동적으로 바꿔봅시다. 우선 setting.conf를 텍스트 에디터로 다음처럼 바꿔서 명렁어 실행 결과를 uptime2.log라는 다른 파일로 출력하도록 설정합니다.

  • 파일2 설정 파일 변경

    UPTIME_FILENAME="/var/tmp/uptime2.log"
    

그리고 프로세스에 HUP 시그널을 보내기 위해 다른 단말을 열어서 ps 명령어로 지금 실행 중인 PID를 조사합니다. sig-hup.sh의 PID가 29658이라면 다음처럼 kill 명령어 -s 옵션으로 HUP 시그널을 보냅니다.

  • HUP 시그널을 보내면 설정 파일을 다시 읽음

    $ kill -s HUP 29658
    

그러면 지금까지 /var/tmp/uptime.log에 출력하던 로그가 /var/tmp/uptime2.log로 바뀌게 됩니다. 이렇게 해서 프로세스를 멈추지 않고 동적으로 설정을 바꿀 수있습니다.

   

주의사항

  • 스크립트는 무한 반복이므로 종료하려면 kill -9 명령어를 사용하거나 실행한 터미널에서 Ctrl + C 를 입력합니다.