검색 엔진의 방문이 늘어나고 있군...

Posted
Filed under 쉘 스크립트
참조 원문 : How to Write Linux Init Scripts Based on LSB Init Standard

  LSB란 Linux Standard Base의 약자로서 리눅스 재단이 배포판 사이의 차이점을 줄여 다른 배포판으로 이식할 때 드는 비용을 줄이기 위해 만든 표준입니다. Init 스크립트도 표준화된 것들 중 하나입니다.

  Init 스크립트는 소프트웨어나 서비스를 시작하거나 중단할 때 사용합니다. 예를 들어 postgresql 소프트웨어를 사용하고 있다면 /etc/init.d/postgresql 이라는 Init 스크립트를 가지고 있을 것이며 인자로 start, stop, restart, reload, force-reload, status를 사용할 수 있습니다.

  LSB 호환 Init 스크립트는 아래 사항을 지켜야 합니다.
  • 최소한 'start, stop, restart, force-reload, status'를 제공해야 한다.
  • 적절한 exit code를 return해야 한다.
  • 실행 의존성(run-time dependencies)을 문서화해야 한다.
  추가적으로 이 스크립트들은 메시지를 남기기 위해 "log_success_msg"나 "log_failure_msg" 같은 init.d 함수를 사용할 수 있습니다.

  LSB는 /lib/lsb/init-functions에 있는 기본 함수들을 제공합니다. Init 스크립트로 실행되는 프로세스들은 /var/run/ 디렉토리에 프로세스의 pid를 기록하는데 이것은 Init 스크립트가 프로세스의 상태를 조사할 때 큰 도움이 됩니다.

  이제 Init 스크립트를 작성해봅시다. 먼저 아래처럼 헤더를 넣습니다.
### BEGIN INIT INFO
# Provides:          my_daemon
# Required-Start:    postgresql networking
# Required-Stop:     postgresql networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: This is a test daemon
# Description:       This is a test daemon
#                    This provides example about how to
#                    write a Init script.
### END INIT INFO
  Provides에는 해당 Init 스크립트가 제공하는 기능(facility=서비스)을 적습니다. 이 이름은 유일해야 합니다.

  Requred-Start에는 이 서비스를 시작하기 전에 작동하고 있어야 하는 일련의 기능들을 적습니다. 이 예제의 경우 postgresql과 networking이 미리 실행되어 있어야 함을 나타내고 있습니다. 기억해야 할 점은 이 'postgresql'가 'Provides: postgresql'이라고 적힌 별도의 Init 스크립트를 가지고 있어야 한다는 것입니다. 이를 통해 부팅 시 의존성을 보장합니다. 'inserv' 명령어나 'update-rc.d' 명령어를 사용할 때 이 의존성을 바탕으로 대상 런레벨 디렉토리에 적절한 순번을 매겨 집어넣게 됩니다.
/etc/rc2.d/S12postgresql
/etc/rc2.d/S03networking
/etc/rc2.d/S13my_daemon
  예를 들어 위와 같은 엔트리가 있을 경우 networking, postgresql, my_daemon 순서로 실행됩니다.

  Required-Stop에는 이 기능을 중단한 후에만 중단할 수 있는 일련의 기능들을 적습니다. 이 예제의 경우 my_daemon이 중단된 후에만 postgresql과 networking 기능을 중단할 수 있습니다.

  Default-Start Default-Stop에는 이 서비스가 시작되거나 중단돼야 하는 런레벨을 정의합니다.

  Short-Description Description에는 해당 기능에 대한 설명을 적습니다. Short-Description에는 한 줄만 적을 수 있으며, Description에는 여러 줄에 걸쳐 적을 수 있습니다.

  아래는 실제 Init 스크립트의 예입니다.
### BEGIN INIT INFO
# Provides:          my_daemon
# Required-Start:    postgresql networking
# Required-Stop:     postgresql networking
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: This is a test daemon
# Description:       This is a test daemon
#                    This provides example about how to
#                    write a Init script.
### END INIT INFO

# Using the lsb functions to perform the operations.
. /lib/lsb/init-functions
# Process name ( For display )
NAME=my-daemon
# Daemon name, where is the actual executable
DAEMON=/home/user1/my_daemon
# pid file for the daemon
PIDFILE=/var/run/my_daemon.pid

# If the daemon is not there, then exit.
test -x $DAEMON || exit 5

case $1 in
 start)
  # Checked the PID file exists and check the actual status of process
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON "$NAME process" && status="0" || status="$?"
   # If the status is SUCCESS then don't need to start again.
   if [ $status = "0" ]; then
    exit # Exit
   fi
  fi
  # Start the daemon.
  log_daemon_msg "Starting the process" "$NAME"
  # Start the daemon with the help of start-stop-daemon
  # Log the message appropriately
  if start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON ; then
   log_end_msg 0
  else
   log_end_msg 1
  fi
  ;;
 stop)
  # Stop the daemon.
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON "Stoppping the $NAME process" && status="0" || status="$?"
   if [ "$status" = 0 ]; then
    start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
    /bin/rm -rf $PIDFILE
   fi
  else
   log_daemon_msg "$NAME process is not running"
   log_end_msg 0
  fi
  ;;
 restart)
  # Restart the daemon.
  $0 stop && sleep 2 && $0 start
  ;;
 status)
  # Check the status of the process.
  if [ -e $PIDFILE ]; then
   status_of_proc -p $PIDFILE $DAEMON "$NAME process" && exit 0 || exit $?
  else
   log_daemon_msg "$NAME Process is not running"
   log_end_msg 0
  fi
  ;;
 reload)
  # Reload the process. Basically sending some signal to a daemon to reload
  # it configurations.
  if [ -e $PIDFILE ]; then
   start-stop-daemon --stop --signal USR1 --quiet --pidfile $PIDFILE --name $NAME
   log_success_msg "$NAME process reloaded successfully"
  else
   log_failure_msg "$PIDFILE does not exists"
  fi
  ;;
 *)
  # For invalid arguments, print the usage message.
  echo "Usage: $0 {start|stop|restart|reload|status}"
  exit 2
  ;;
esac
  위 스크립트는 LSBInit 스크립트 작성을 위한 템플릿입니다. DAEMON, PIDFILE, NAME 변수, 헤더 등을 적절히 바꿔 사용할 수 있습니다.

  LSB가 제공하는 함수에 대해 더 알고 싶다면 InitScript Functions를 참조하시기 바랍니다.

  Init 스크립트를 작성한 후 자동으로 시작되거나 중단되게 만들려면 아래 형식으로 명령어를 실행합니다.(데비안 계열 기준)
update-rc.d filename defaults
  이 명령어는 지정한 런레벨에 의존성을 고려한 적절한 순번을 가진 'S'와 'K' 엔트리를 추가합니다.
2013/07/02 14:14 2013/07/02 14:14