Пишем 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», исправьте.
Спасибо! Поправил.
Вы эти скрипты сами запускали?
Там куча ошибок логических. Чем их исправлять, проще самому переписать.
Да, я прежде чем постить заметку, проверяю! Возможно плагин изменил содержание кода, версия или тип ОС другой.