참조 원문 : 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’ 엔트리를 추가합니다.