Запуск довільної програми як демон із init script


10

Мені потрібно встановити програму як послугу в Red Hat. Він не фоновий, не керує своїм PID-файлом або не керує власними журналами. Він просто працює і друкується на STDOUT та STDERR.

Використовуючи стандартні скрипти init як посібники, я розробив наступне:

#!/bin/bash
#
#   /etc/rc.d/init.d/someprog
#
# Starts the someprog daemon
#
# chkconfig: 345 80 20
# description: the someprog daemon
# processname: someprog
# config: /etc/someprog.conf

# Source function library.
. /etc/rc.d/init.d/functions

prog="someprog"
exec="/usr/local/bin/$prog"
[ -e "/etc/sysconfig/$prog" ] && . "/etc/sysconfig/$prog"
lockfile="/var/lock/subsys/$prog"
RETVAL=0

check() {
    [ `id -u` = 0 ] || exit 4
    test -x "$exec" || exit 5
}

start() {
    check
    if [ ! -f "$lockfile" ]; then
        echo -n $"Starting $prog: " 
        daemon --user someproguser "$exec"
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch "$lockfile"
        echo
    fi
    return $RETVAL
}

stop() {
    check
    echo -n $"Stopping $prog: "
    killproc "exec"
    RETVAL=$?
    [ $RETVAL -eq 0 ] && rm -f "$lockfile"
    echo
    return $RETVAL
}

restart() {
    stop
    start
}   

case "$1" in
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    restart
    ;;
status)
    status "$prog"
    RETVAL=$?
    ;;
*)
    echo $"Usage: $0 {start|stop|restart|status}"
    RETVAL=2
esac

exit $RETVAL

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

  • коли я запускаю його з service someprog startпрограмою, виводить на термінал, і команда не завершується.
  • якщо я CTRL-C, він надрукує "Сеанс припинено, вбивство снаряд ... ... вбито. НЕПРАВНО". Я повинен зробити це, щоб знову повернути свою оболонку.
  • тепер, коли я запускаю, service someprog statusвін каже, що він працює і перераховує свій PID. Я бачу це psтак, що він працює.
  • тепер, коли я запускаю, service someprog stopвін не зупиняється. Я можу переконатися, що він все ще працює ps.

Що потрібно змінити, щоб someprogвін надсилався у фоновий режим і керувався як служба?

Редагувати: Зараз я знайшов пару споріднених питань, жодне з них не має фактичної відповіді, окрім "робити щось інше":

Редагувати: ця відповідь на подвійне розгортання, можливо, вирішила мою проблему, але тепер моя програма сама подвійні форки та працює: https://stackoverflow.com/a/9646251/898699


Ви запускаєте програму за допомогою утиліти "демон", наданої libslack. libslack.org/daemon/#documentation У цьому випадку програму можна зупинити як ім'я демона -n - стоп. Також спробуйте перенаправити результат (при запуску програми) на файл або / dev / null і перевірте.
Анкіт

2
Залежно від вашої версії redhat, ви можете просто зробити просту обгортку для неї на початку та зателефонувати безпосередньо у програму. Тоді upstart керуватиме послугою для вас. Це все-таки EL6.
Метью Іфе

Відповіді:


1

Команда "не завершується", оскільки daemonфункція не запускає вашу програму у фоновому режимі для вас. Вам потрібно буде додати &в кінець своєї daemonкоманди так:

daemon --user someproguser $exec &

Якщо someprogце не вдається SIGHUP, слід запустити команду, nohupщоб переконатися, що ваш процес не буде отримувати, SIGHUPщо повідомляє процес завершити, коли вихідна оболонка закінчується. Це виглядатиме так:

daemon --user someproguser "nohup $exec" &

У вашій stopфункції killproc "exec"нічого не робить, щоб зупинити вашу програму. Він повинен читати так:

killproc $exec

killprocпотрібен повний шлях до вашої програми, щоб правильно її зупинити. У мене були проблеми з killprocминулим, тому ви також можете просто вбити PID у PIDFILE, до якого слід писати someprogPID, таким чином:

cat $pidfile | xargs kill

Ви можете написати PIDFILE так:

ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile

де $pidfileвказує на /var/run/someprog.pid.

Якщо ви хочете [OK] або [FAILED] у своїй stopфункції, слід скористатися функціями successта failureвід /etc/rc.d/init.d/functions. Вам не потрібні ці startфункції, тому що daemonвиклик відповідного вам.

Вам також потрібні лише лапки навколо рядків з пробілами. Це, однак, вибір стилю, так що саме від вас.

Усі ці зміни виглядають приблизно так:

#!/bin/bash
#
#   /etc/rc.d/init.d/someprog
#
# Starts the someprog daemon
#
# chkconfig: 345 80 20
# description: the someprog daemon
# processname: someprog
# config: /etc/someprog.conf

# Source function library.
. /etc/rc.d/init.d/functions

prog=someprog
exec=/usr/local/bin/$prog
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/$prog
pidfile=/var/run/$prog
RETVAL=0

check() {
    [ `id -u` = 0 ] || exit 4
    test -x $exec || exit 5
}

start() {
    check
    if [ ! -f $lockfile ]; then
        echo -n $"Starting $prog: " 
        daemon --user someproguser "nohup $exec" &
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
          touch $lockfile
          ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile
        fi
        echo
    fi
    return $RETVAL
}

stop() {
    check
    echo -n $"Stopping $prog: "
    killproc $exec && cat $pidfile | kill
    RETVAL=$?
    if [ $RETVAL -eq 0 ]; then
      rm -f $lockfile
      rm -f $pidfile
      success; echo
    else
      failure; echo
    fi
    echo
    return $RETVAL
}

restart() {
    stop
    start
}   

case "$1" in
start)
    start
    ;;
stop)
    stop
    ;;
restart)
    restart
    ;;
status)
    status $prog
    RETVAL=$?
    ;;
*)
    echo $"Usage: $0 {start|stop|restart|status}"
    RETVAL=2
esac

exit $RETVAL

Вибачте, для отримання правильної відповіді минуло майже 4,5 роки.
Ступорман

-1

Якщо це ваша програма, напишіть її як належний демон. Особливо якщо його для перерозподілу. :)

Ви можете спробувати моніт . А може, щось на кшталт runit або daemontools. Ті, хто може, не мають легко доступних пакетів. Daemontools - від DJB, якщо це впливає на ваше рішення (в будь-якому напрямку)


-1

Я провів ще кілька досліджень, і, здається, що відповідь - "ти цього не можеш зробити". Програма, яку потрібно запустити, повинна фактично демонструвати себе належним чином: розщедритися та від'єднати його стандартні файлові файли, відключитися від терміналу та розпочати новий сеанс.

Редагувати: мабуть, я помиляюся - подвійне розгортання спрацювало б. https://stackoverflow.com/a/9646251/898699


Зробити це можна, скориставшись операцією, як зазначено в коментарях.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.