Як правильно додати користувацький демон в init.d?


26

У мене є власний демон сервера 3-х сторонніх додатків, який можна запускати і зупиняти через пару командних рядків. Мені потрібен цей демон для запуску, коли система запускається і правильно зупиняється при відключенні системи. Як я правильно це реалізую? Чи достатньо скопіювати якийсь сценарій всередині /etc/init.d та змінити його відповідно?

Відповіді:


16

init.d - стара, застаріла система запуску демонів; це було витіснено вискочкою . Перевага "Upstart" полягає в тому, що вони набагато простіші в налаштуванні і дозволяють належної послідовності ініціалізації завдань.

Файли конфігурації для запуску в прямому ефірі в / etc / init, і якщо ваш демон не має попередніх реквізитів, він може бути таким же простим, як tty1.conf:

# tty1 - getty
#
# This service maintains a getty on tty1 from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -8 38400 tty1

у такому випадку ви можете скопіювати цей файл та змінити на смак. Більш складні конфігурації найкраще зафіксувати на початку сайту та в інших записах у / etc / init.

додано у відповідь на коментар

Незалежно від того, використовуєте ви upstart або init.d, вам все одно знадобиться певний спосіб визначити, коли Firebird правильно ініціалізований. На жаль, сам Firebird, здається, не має хорошого способу перевірити, чи встановлений він та працює . Тому рекомендація вставляти свою програму запуск у /etc/rc.local, безумовно, найпростіша, а на Ubuntu - принаймні - гарантовано запуститись якомога пізніше в процесі завантаження.


1
Насправді мій демон залежить від сервера баз даних Firebird, який використовує init.d.
Іван

12

якщо ви не хочете перейти на UPSTART, але хочете класичний підхід, ви повинні:

ПРИМІТКА. Я зберігаю службу та програму з однаковою назвою в різних каталогах (але ви можете змінити це, якщо це відображається у вашому файлі служби). змініть "myscriptname" та "myprogramname" на справжні імена!

  1. збережіть свою програму, яка працюватиме як послуга в / usr / sbin

    sudo cp myprogramname /usr/sbin/myscriptname

  2. створити базовий сценарій запуску (використовувати /etc/init.d/skeleton в якості посилання)

  3. перемістіть цей скрипт у /etc/init.d

    sudo mv /etc/init.d/myscriptname

  4. надати цьому сценарію виконавчий дозвіл (я використовував 775, але ви можете встановити його нижче)

    sudo chmod 755 /etc/init.d/myscriptname

  5. goto /etc/init.d

    cd /etc/init.d

  6. включити до списку запуску з низьким пріоритетом запуску

    sudo update-rc.d myscriptname defaults 97 03

перезавантажте машину та перевірте, чи сервіс запустився належним чином

sudo ps -A --sort cmd

якщо ваша служба не запускається належним чином, спершу слід перевірити, чи працює вона, коли дзвонить вручну:

cd /etc/init.d
sudo service myscriptname start

нижче я включаю зразок службового файлу, який фактично працює. порівняйте його зі службою скелету, щоб зрозуміти, що потрібно налаштувати. ПРИМІТКА: це працює на Ubuntu 12.04 Amazon хмара AWS EC2 класична реалізація LAMP (також на Kubuntu 15.10).

#! /bin/sh
### BEGIN INIT INFO
# Provides:          
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Sample_GT02 daemon startup script
# Description:       Sample Server for GT02 class 
### END INIT INFO

# Author: Tony Gil 
#

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Sample Daemon"
NAME=sampleserver_gt02
DAEMON=/usr/sbin/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
CHUID=root

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
   # Return
   #   0 if daemon has been started
   #   1 if daemon was already running
   #   2 if daemon could not be started
   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
      || return 1
   start-stop-daemon --start --quiet --chuid $CHUID --pidfile $PIDFILE --exec $DAEMON -- \
      $DAEMON_ARGS \
      || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
   # Return
   #   0 if daemon has been stopped
   #   1 if daemon was already stopped
   #   2 if daemon could not be stopped
   #   other if a failure occurred
   start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
   RETVAL="$?"
   [ "$RETVAL" = 2 ] && return 2
   # Wait for children to finish too if this is a daemon that forks
   # and if the daemon is only ever run from this initscript.
   # If the above conditions are not satisfied then add some other code
   # that waits for the process to drop all resources that could be
   # needed by services started subsequently.  A last resort is to
   # sleep for some time.
   start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
   [ "$?" = 2 ] && return 2
   # Many daemons don't delete their pidfiles when they exit.
   rm -f $PIDFILE
   return "$RETVAL"
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
   #
   # If the daemon can reload its configuration without
   # restarting (for example, when it is sent a SIGHUP),
   # then implement that here.
   #
   start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
   return 0
}

case "$1" in
  start)
   [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
   do_start
   case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
   esac
   ;;
  stop)
   [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
   do_stop
   case "$?" in
      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
   esac
   ;;
  #reload|force-reload)
   #
   # If do_reload() is not implemented then leave this commented out
   # and leave 'force-reload' as an alias for 'restart'.
   #
   #log_daemon_msg "Reloading $DESC" "$NAME"
   #do_reload
   #log_end_msg $?
   #;;
  restart|force-reload)
   #
   # If the "reload" option is implemented then remove the
   # 'force-reload' alias
   #
   log_daemon_msg "Restarting $DESC" "$NAME"
   do_stop
   case "$?" in
     0|1)
      do_start
      case "$?" in
         0) log_end_msg 0 ;;
         1) log_end_msg 1 ;; # Old process is still running
         *) log_end_msg 1 ;; # Failed to start
      esac
      ;;
     *)
        # Failed to stop
      log_end_msg 1
      ;;
   esac
   ;;
  *)
   #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
   echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
   exit 3
   ;;
esac

:

1
@jakeGould ви насправді знайшли час, щоб переформатувати "мій" код. це означає, що ви його протестували і він працював на вас?
tony gil

1
це працювало для мене
Mario S

Невже зараз не померлий мертвий на користь системного?
Gillespie

Дійсно, на моєму недавньому Ubuntu навіть не встановлено. Сценарії SysV init ніколи не загинуть.
Кріс Надович

8

Зробіть копію /etc/init.d/skeleton та відредагуйте її у відповідних місцях, щоб запустити / зупинити / перезапустити службу. Це дуже добре коментується, тож ви зможете за короткий час створити робочий сценарій init.d.


Це означає, що вам також потрібно створити символьні посилання в rcX.d. Однак оновлення Ubuntu знищить всі ваші власні символічні посилання.
Робін Хсу

2
  • Додайте свої команди до /etc/rc.local
  • Так що ваш демон буде автоматично запускатися при запуску системи.

1

pleaserunце сценарій рубіну, який намагається вирішити проблему автоматичного створення сценарію init за допомогою однієї команди. цитуючи з його сторінки:

"За допомогою pleaserun ви можете генерувати такі пускові установки / скрипти / що завгодно:

запуск програм
вискочка
Systemd
runit
SysV INIT »

Він також визначає, яка система init використовується, тому генерує сценарій відповідно.


не впевнений, що, будь ласка, також здійснює ведення журналу, але цей інший також має реєстрацію: gist.github.com/naholyr/4275302
Costin Gușă
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.