Jak mogę uruchomić skrypt powłoki jako demon w Redhat?

12

Mam skrypt powłoki, który jest w zasadzie jednostronnym programem z logowaniem, który próbuję uruchomić ze skryptu inicjującego. Korzystam z daemonfunkcji wewnątrz, /etc/init.d/functionsaby go uruchomić, ponieważ wydaje się, że Redhat nie jest start-stop-daemondostępny. Kiedy wywołam skrypt skryptowy init ( /etc/init.d/script start), pozostaje on na pierwszym planie, a nie kończy i nie uruchamia procesu. Jaki jest właściwy sposób demonizacji tego skryptu?

Skrypt do uruchomienia:

# 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

skrypt inicjujący:

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

Ostatnie ~ 20 linii wykonania przy pomocy bash -vx:

+ 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
bshacklett
źródło
Przydaje mi się, że uruchamiasz ten skrypt bash -vx ...i publikujesz ostatnie wiersze, abyśmy mogli zobaczyć, co pozostaje na pierwszym planie.
Hauke ​​Laging 18.04.13
1
Nie przejmuj się korzystaniem z tego prawa i idź z daemon, jest też pakiet RPM . Przy okazji, istnieje wiele narzędzi do monitorowania dzienników ( zacznij tutaj ).
sr_
Hauke, masz na myśli użycie pierwszego wiersza #!/bin/bash -vx? Próbowałem to zrobić, ale nie wytworzyło to takiego samego wyniku ze skryptu inicjującego, jak w przypadku bezpośredniego uruchomienia skryptu powłoki.
bshacklett
@ bshacklett możesz sprawdzić funkcję dowolnego skryptu inicjującego (faktycznie dowolnego skryptu powłoki), uruchamiając go jawnie za pomocą bash -vx, tj. bash -vx /etc/init.d/script start.
sr_
1
@bshacklett Wrt logs, przyjrzałbym się bliżej logstash . Sklep może być zasilany dziennikami bezpośrednio z Log4j, ale agent logstash może również monitorować pliki dzienników
sr_

Odpowiedzi:

2

Znalazłem skrypt w http://www.linuxforums.org/forum/programming-scripting/190279-daemon-etc-init-d-functions-does-not-return-launching-process.html#post897522 które udało mi modyfikować według własnych potrzeb. Ręcznie śledzi PID i tworzy plik PID za pomocą pidof. Skończyło się na tym, że musiałem to zmodyfikować, pgrepponieważ pidofnie mogłem zobaczyć PID mojego skryptu. Po tej modyfikacji działało dobrze. * Uwaga: pgrep wydaje się działać tylko wtedy, gdy pełna nazwa skryptu ma mniej niż 15 znaków

Oto, z czym skończyłem:

#!/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 $?
bshacklett
źródło
0

Nie znam Redhata, ale daemon $prog &wydaje mi się dziwny. Jeśli istnieje już funkcja do demonizacji, dlaczego konieczne jest (i przydatne) umieszczenie tej funkcji w tle? Dlatego spróbuj bez &.

Hauke ​​Laging
źródło
4
To nie jest źle /etc/init.d/functionsdefiniuje daemonfunkcję, która oczekuje, że jej argument się zdemonizuje, zajmuje się tylko takimi rzeczami jak zmiana użytkownika, ustawianie ulimitów, sprawdzanie (nie tworzenie!) pliku pid ... Najlepszym zastosowaniem tej daemonfunkcji jest zastąpienie jej libslackdaemon ;)
sr_
Przepraszam, ikona & była tam w pewnym momencie, gdy rozwiązywałem problemy. Nie chciałem umieszczać tego w tym poście.
bshacklett 18.04.13