Пишем Init скрипт
Инициализация — важнейшая процедура, лежащая в основе любой операционной системы на основе Unix/Linux для управления работой каждого скрипта и службы.
Я описывал в своих статьях процесс создания скриптов для systemD/Upstart и сейчас я хотел бы написать о написании init скриптов. Тема не новая и используется давно, но я большую часть своих тем беру именно из черновиков, которые накопились за года 3-4. У меня не хватает времени на все публикации + наполнять контент максимально (по крайней мере, сразу) и по этому, имеет что имеем. Но не смотря на это, у меня уже довольно много читателей — и это хорошо, это радует!
По сути, инициализация следует за этим процессом:
- Загрузка сервера.
- Запуск init процесса (обычно как PID 1).
- Запуск предопределенного набора задач для запуска активируется последовательно.
Инициализация отвечает за то, чтобы сервер мог загрузиться и отключиться. В некоторых Unix/Linux дистрибутивах используется стандартный процесс инициализации init/systemD/Upstart.
Пишем Upstart скрипт
И так, хотелось бы рассказать как можно запускать томкат. Но для начала, нужно узнать какой механизм инициализации используется:
# ps -s1| awk '{print $4}'| grep -Ev "CMD"
Т.к речь идет о sysv init/Upstart, то и продолжим тему.
PS: Вот еще полезное чтиво:
Система инициализации в Unix/Linux
Система инициализации SysVinit
INIT скрипт может иметь следующие состояния:
- start — Служит командой для запуска службы.
- stop — Выполняет остановку службы.
- restart — Перезапуст службы, а по факту — остановка и затем запуск сервиса.
- reload — Перезагрузка службы, т.е команда для перечитывания конфигурации без перезапуска или остановки службы.
- force-reload — Перезагрузка конфигурации (перечитать конфиг), если служба поддерживает это. В противном случае — выполнит перезапуск службы.
- status — Покажет состояние службы.
Вот скилет скрипта для использования:
#!/bin/bash -x
#
# Source function library.
. /etc/rc.d/init.d/functions
<define any local shell functions used by the code that follows>
case "$1" in
start)
echo -n "Starting <servicename> services: "
<start daemons, perhaps with the daemon function>
touch /var/lock/subsys/<servicename>
;;
stop)
echo -n "Shutting down <servicename> services: "
<stop daemons, perhaps with the killproc function>
rm -f /var/lock/subsys/<servicename>
;;
status)
<report the status of the daemons in free-form format,
perhaps with the status function>
;;
restart)
<restart the daemons, normally with $0 stop; $0 start>
;;
reload)
<cause the service configuration to be reread, either with
kill -HUP or by restarting the daemons, possibly with
$0 stop; $0 start>
;;
probe)
<optional. If it exists, then it should determine whether
or not the service needs to be restarted or reloaded (or
whatever) in order to activate any changes in the configuration
scripts. It should print out a list of commands to give to
$0; see the description under the probe tag below.>
;;
*)
echo "Usage: <servicename> {start|stop|status|reload|restart[|probe]"
exit 1
;;
esac
Данный каркас можно юзать для любых целей.
Примеры Init скрипта
Приведу наглядный пример запуска томката.
Запуск TOMCAT с init
Создадим init скрипт для запуска:
# vim /etc/init.d/tomcat9
И приводим к виду:
#!/bin/bash -x
#
# Provides: tomcat9
# Required-Start: $local_fs $remote_fs $network
# Required-Stop: $local_fs $remote_fs $network
# Should-Start: $named
# Should-Stop: $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start Tomcat.
# Description: Start the Tomcat servlet engine.
### END INIT INFO
export CATALINA_HOME=/usr/local/tomcat9
export JAVA_HOME=/usr/local/jdk1.8.0_131
export PATH=$JAVA_HOME/bin:$PATH
service_name="tomcat9"
start() {
echo "Starting Tomcat 9..."
/bin/su -s /bin/bash tomcat -c $CATALINA_HOME/bin/startup.sh
}
stop() {
echo "Stopping Tomcat 9..."
/bin/su -s /bin/bash tomcat -c $CATALINA_HOME/bin/shutdown.sh
}
status() {
if (( $(ps -ef | grep -v grep | grep $service_name | wc -l) > 0 )); then
echo "$service_name is running!!!"
else
echo "$service_name is down!!!"
fi
}
case $1 in
start|stop|status) $1;;
restart) stop; start;;
*) echo "Usage : $0 <start|stop|restart>"; exit 1;;
esac
exit 0
Даем права на запуск (на исполнение):
# chmod 755 /etc/init.d/tomcat9
ИЛИ:
# chmod +x /etc/init.d/tomcat9
Запускаем томкат:
# service tomcat9 start
Открываем браузер и смотрим что вышло!
Вот еще один скрипт:
#!/bin/bash -x
DAEMON_PATH="/home/wes/Development/projects/myapp"
DAEMON=myapp
DAEMONOPTS="-my opts"
NAME=myapp
DESC="My daemon description"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
case "$1" in
start)
printf "%-50s" "Starting $NAME..."
cd $DAEMON_PATH
PID=`$DAEMON $DAEMONOPTS > /dev/null 2>&1 & echo $!`
#echo "Saving PID" $PID " to " $PIDFILE
if [ -z $PID ]; then
printf "%s\n" "Fail"
else
echo $PID > $PIDFILE
printf "%s\n" "Ok"
fi
;;
status)
printf "%-50s" "Checking $NAME..."
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
printf "%s\n" "Process dead but pidfile exists"
else
echo "Running"
fi
else
printf "%s\n" "Service not running"
fi
;;
stop)
printf "%-50s" "Stopping $NAME"
PID=`cat $PIDFILE`
cd $DAEMON_PATH
if [ -f $PIDFILE ]; then
kill -HUP $PID
printf "%s\n" "Ok"
rm -f $PIDFILE
else
printf "%s\n" "pidfile not found"
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {status|start|stop|restart}"
exit 1
esac
Подойдет к большинству скриптов, а для остальных — можно отредактировать немного.
И, вот еще полезный довольно вариант:
#!/bin/sh
### BEGIN INIT INFO
# Provides:
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
dir=""
cmd=""
user=""
name=`basename $0`
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"
get_pid() {
cat "$pid_file"
}
is_running() {
[ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1
}
case "$1" in
start)
if is_running; then
echo "Already started"
else
echo "Starting $name"
cd "$dir"
if [ -z "$user" ]; then
sudo $cmd >> "$stdout_log" 2>> "$stderr_log" &
else
sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" &
fi
echo $! > "$pid_file"
if ! is_running; then
echo "Unable to start, see $stdout_log and $stderr_log"
exit 1
fi
fi
;;
stop)
if is_running; then
echo -n "Stopping $name.."
kill `get_pid`
for i in 1 2 3 4 5 6 7 8 9 10
# for i in `seq 10`
do
if ! is_running; then
break
fi
echo -n "."
sleep 1
done
echo
if is_running; then
echo "Not stopped; may still be shutting down or shutdown may have failed"
exit 1
else
echo "Stopped"
if [ -f "$pid_file" ]; then
rm "$pid_file"
fi
fi
else
echo "Not running"
fi
;;
restart)
$0 stop
if is_running; then
echo "Unable to stop, will not attempt to start"
exit 1
fi
$0 start
;;
status)
if is_running; then
echo "Running"
else
echo "Stopped"
exit 1
fi
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit 0
Вот и все, статья «Пишем Init скрипт» завершена.
Неверно указана ссылка «Система инициализации SysVinit», исправьте.
Спасибо! Поправил.
Вы эти скрипты сами запускали?
Там куча ошибок логических. Чем их исправлять, проще самому переписать.
Да, я прежде чем постить заметку, проверяю! Возможно плагин изменил содержание кода, версия или тип ОС другой.