Bir kabuk betiğini Redhat altında bir daemon olarak nasıl çalıştırabilirim?


12

Ben aslında bir init betiğinden çalıştırmak için çalışıyorum bazı günlüğü ile bir astar olan bir kabuk komut dosyası var. Redhat kullanılabilir görünmüyor gibi, daemoniçinde /etc/init.d/functionsçalıştırmak için işlevi kullanıyorum start-stop-daemon. Ben init betiği ( /etc/init.d/script start) çağırdığınızda , işlemin tamamlanması ve bırakılması yerine ön planda kalır. Bu senaryoyu arka plana almamın doğru yolu nedir?

Çalıştırılacak komut dosyası:

# conf file where variables are defined
. /etc/script.conf

echo "Starting..." | logger -i
echo "Monitoring $LOG_LOCATION." | logger -i
echo "Sending to $MONITOR_HOST:$MONITOR_PORT." | logger -i

tail -n 1 -F $LOG_LOCATION |
grep WARN --line-buffered  |
/usr/bin/nc -vv $MONITOR_HOST $MONITOR_PORT 2>&1 |
logger -i

init betiği:

#!/bin/bash


# Source Defaults
. /etc/default/script

# Source init functions
. /etc/init.d/functions

prog=/usr/local/bin/script.sh

[ -f /etc/script.conf ] || exit 1

RETVAL=0

start()
{
    # Quit if disabled
    if ! $ENABLED; then
            echo "Service Disabled in /etc/default/script"
            exit 1
    fi

    echo "Starting $prog"

    daemon $prog

    RETVAL=$?

    return $RETVAL
}

stop ()
{
    echo -n $"Stopping $prog: "
    killproc $prog

    RETVAL=$?

    return $RETVAL
}

reload()
{
    echo "Reload command is not implemented for this service."
    return $RETVAL
}

restart()
{
    stop
    start
}

condrestart()
{
    echo "Not Implemented."
}

# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status $prog
        ;;
    restart)
        restart
        ;;
    reload)
        reload
        ;;
    condrestart)
        condrestart
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
        RETVAL=1
esac

Bash -vx ile son ~ 20 yürütme satırı:

+ case "$1" in
+ start
+ true
+ echo 'Starting /usr/local/bin/script.sh'
Starting /usr/local/bin/script.sh
+ daemon /usr/local/bin/script.sh
+ local gotbase= force=
+ local base= user= nice= bg= pid=
+ nicelevel=0
+ '[' /usr/local/bin/script.sh '!=' /usr/local/bin/script.sh ']'
+ '[' -z '' ']'
+ base=script.sh
+ '[' -f /var/run/script.sh.pid ']'
+ '[' -n '' -a -z '' ']'
+ ulimit -S -c 0
+ '[' -n '' ']'
+ '[' color = verbose -a -z '' ']'
+ '[' -z '' ']'
+ initlog -q -c /usr/local/bin/script.sh

Bu komut dosyasını bash -vx ...son satırlarda çalıştırıp yayınlamanız ön planda olanları görebilmemiz için faydalı görünüyor .
Hauke ​​Laging

1
Bu hakkın kullanımını alma zahmet ile gitmeyin daemon, orada bir RPM paket de. Btw, orada birçok günlük izleme aracı var ( buradan başlayın ).
sr_

Hauke, ilk satırını mı demek istiyorsun #!/bin/bash -vx? Bunu yapmayı denedim, ancak kabuk komut dosyasını doğrudan çalıştırırsam init komut dosyasından aynı çıktıyı üretmedi.
bshacklett

@bshacklett, herhangi bir init betiğinin (herhangi bir kabuk betiğinin aslında) işlevini açıkça bash -vx, yani ile çalıştırarak inceleyebilirsiniz . bash -vx /etc/init.d/script start.
sr_

1
@bshacklett Wrt günlükleri, logstash'a daha yakından bakardım . Mağaza günlükleri doğrudan Log4j'den besleyebilir, ancak logstash aracısı günlük dosyalarını da izleyebilir
sr_

Yanıtlar:


2

Ben bir senaryonubulmuş http://www.linuxforums.org/forum/programming-scripting/190279-daemon-etc-init-d-functions-does-not-return-launching-process.html#post897522 ben başardı benim ihtiyaçlarına göre değiştirmek için. Manuel olarak PID'yi izler ve kullanarak bir PID dosyası oluşturur pidof. Ben kullanımına bu değiştirmek zorunda sona erdi pgrepolarak pidofSenaryomun PıD'YI göremedi. Bu modifikasyondan sonra iyi çalıştı. * Not, pgrep yalnızca tam komut dosyası adı 15 karakterin altındaysa çalışır

İşte sonuçta:

#!/bin/bash
#
# 
#
# Start on runlevels 3, 4 and 5. Start late, kill early.
# chkconfig: 345 95 05
#
#
#!/bin/bash

# absolute path to executable binary
progpath='/usr/local/bin/script.sh'

# arguments to script
opts=''

# binary program name
prog=$(basename $progpath)

# pid file
pidfile="/var/run/${prog}.pid"

# make sure full path to executable binary is found
! [ -x $progpath ] && echo "$progpath: executable not found" && exit 1

eval_cmd() {
  local rc=$1
  if [ $rc -eq 0 ]; then
    echo '[  OK  ]'
  else
    echo '[FAILED]'
  fi
  return $rc
}

start() {
  # see if running
  local pids=$(pgrep $prog)

  if [ -n "$pids" ]; then
    echo "$prog (pid $pids) is already running"
    return 0
  fi
  printf "%-50s%s" "Starting $prog: " ''
  $progpath $opts &

  # save pid to file if you want
  echo $! > $pidfile

  # check again if running
  pgrep $prog >/dev/null 2>&1
  eval_cmd $?
}

stop() {
  # see if running
  local pids=$(pgrep $prog)

  if [ -z "$pids" ]; then
    echo "$prog not running"
    return 0
  fi
  printf "%-50s%s" "Stopping $prog: " ''
  rm -f $pidfile
  kill -9 $pids
  eval_cmd $?
}

status() {
  # see if running
  local pids=$(pgrep $prog)

  if [ -n "$pids" ]; then
    echo "$prog (pid $pids) is running"
  else
    echo "$prog is stopped"
  fi
}

case $1 in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    sleep 1
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart}"
    exit 1
esac

exit $?

0

Redhat'ı bilmiyorum ama daemon $prog &bana garip geliyor. Zaten bir planlama işlevi varsa, bu işlevin kendisini arka plana koymak neden gereklidir (ve yararlıdır)? Böylece olmadan deneyin &.


4
Yanlış değil. kendi argümanı kendini muntazamlaştırmak için bekleyen /etc/init.d/functionsbir daemonişlev tanımlar , sadece kullanıcı değiştirme, ulimits ayarlama, bir pidfile kontrol (oluşturma değil!) gibi şeylerle ilgilenir ... Bu daemonişlevin en iyi kullanımı yerine libslack'sdaemon ile değiştirmektir ;)
sr_

Özür dilerim, & sorun giderirken bir noktada vardı. Bu yazıya eklemek istemedim.
bshacklett
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.