İnit betiğinden rasgele program daemon olarak çalıştırma


10

Red Hat'a servis olarak bir program yüklemem gerekiyor. Kendini arka planlamaz, PID dosyasını yönetmez veya kendi günlüklerini yönetmez. Sadece çalışır ve STDOUT ve STDERR'a yazdırır.

Standart init komut dosyalarını kılavuz olarak kullanarak aşağıdakileri geliştirdim:

#!/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

Benim hatam /etc/init.d dosyasındaki bazı komut dosyalarını kopyalayıp yapıştırmak olabilir. Her durumda, ortaya çıkan hizmet garip davranır:

  • service someprog startprogramı başlattığımda terminale yazdırıyor ve komut tamamlanmıyor.
  • CTRL-C yaparsam, "Oturum sonlandırıldı, kabuğu öldürüyor ... ... öldürüldü. BAŞARISIZ" yazdırır. Kabuk istemimi tekrar almak için bunu yapmak zorundayım.
  • Şimdi çalıştırdığımda service someprog statusçalıştığını söylüyor ve PID'sini listeliyor. İçinde görebiliyorum, psböylece çalışıyor.
  • şimdi service someprog stopkoştuğumda durmuyor. Hala çalıştığını doğrulayabilirim ps.

someprogArka plana gönderilmesi ve hizmet olarak yönetilmesi için neyi değiştirmem gerekir ?

Düzenleme: Şimdi ne "başka bir şey yapmak" dışında gerçek bir cevap ile ilgili birkaç soru bulduk:

Düzenleme: çift çatalla ilgili bu cevap sorunumu çözmüş olabilir, ancak şimdi programımın kendisi çift çatal ve işe yarıyor: https://stackoverflow.com/a/9646251/898699


Programa libslack tarafından sağlanan "daemon" yardımcı programı ile mi başlıyorsunuz? libslack.org/daemon/#documentation Bu durumda program daemon -n name --stop olarak durdurulabilir. Ayrıca, çıktıyı (programı başlatırken) bir dosyaya veya / dev / null'a yönlendirmeyi deneyin ve kontrol edin.
Ankit

2
Redhat sürümünüze bağlı olarak, sadece başlangıçta basit bir sarıcı yapabilir ve doğrudan başlangıçta arayabilirsiniz. Sonra upstart sizin için hizmeti yönetecektir. Bu bir EL6 olayı olsa.
Matthew Ife

Yanıtlar:


1

daemonİşlev uygulamanızı sizin için arka planda çalışmadığından "tamamlanmadı" komutu . Komutunuzun &sonuna şu şekilde bir eklemeniz gerekir daemon:

daemon --user someproguser $exec &

Eğer someprogişlemez SIGHUP, sizinle komutunu çalıştırmalısınız nohupsürecinizle almayacak sağlamak için SIGHUPçıkışa zaman ana kabuk çıkar için sürecinizi söyler. Bu şöyle görünecektir:

daemon --user someproguser "nohup $exec" &

Senin içinde stopişlevi, killproc "exec"programınızı durdurmak için hiçbir şey yapmıyor. Şu şekilde okunmalıdır:

killproc $exec

killprocdüzgün bir şekilde durdurmak için uygulamanızın tam yolunu gerektirir. killprocGeçmişte biraz sorun yaşadım , bu yüzden PIDFILE'daki PID'yi de öldürebilirsin, bunun gibi bir şeyle PID'yi yazmalısın someprog:

cat $pidfile | xargs kill

PIDFILE şöyle yazabilirsiniz:

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

nereye $pidfileişaret ediyor /var/run/someprog.pid.

stopİşlevinizde [Tamam] veya [BAŞARISIZ] istiyorsanız, successve failureişlevlerini kullanmanız gerekir /etc/rc.d/init.d/functions. Bunlara startişlevde ihtiyacınız yoktur çünkü daemonsizin için uygun olanı çağırır.

Ayrıca, yalnızca boşluklu dizelerin tırnak içine alınması gerekir. Bu bir stil seçimi, bu yüzden size kalmış.

Tüm bu değişiklikler şöyle görünür:

#!/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

Üzgünüz, doğru bir cevap almanız yaklaşık 4.5 yıl sürdü.
Stuporman

-1

Bu sizin programınızsa, lütfen uygun bir arka plan programı olarak yazın. Özellikle yeniden dağıtım için. :)

Monit deneyebilirsiniz . Ya da belki runit veya daemontools gibi bir şey. Bunların hazır paketleri olmayabilir. Daemontools, kararınızı etkiliyorsa DJB'den (her iki yönde).


-1

Biraz daha araştırma yaptım ve cevabın "bunu yapamazsın" olduğu anlaşılıyor. Çalıştırılacak programın kendisi düzgün bir şekilde arka plan programı oluşturmalıdır: standart dosya tutamaçlarını çatalla ayırın, terminalden ayırın ve yeni bir oturum başlatın.

Düzenleme: görünüşe göre yanılıyorum - çift çatal işe yarayacaktır. https://stackoverflow.com/a/9646251/898699


Bunu, açıklamalarda belirtildiği gibi upstart komutunu kullanarak yapabilirsiniz.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.