Wie kann ich unter Redhat ein Shell-Skript als Daemon ausführen?

12

Ich habe ein Shell-Skript, das im Wesentlichen einzeilig ist und Protokollierung enthält. Ich versuche, dieses Skript über ein Init-Skript auszuführen. Ich benutze die daemonFunktion innerhalb von /etc/init.d/functions, um es auszuführen, da Redhat anscheinend nicht start-stop-daemonverfügbar ist. Wenn ich das init-Skript ( /etc/init.d/script start) aufrufe, bleibt es im Vordergrund, anstatt den Prozess abzuschließen und laufen zu lassen. Wie kann ich dieses Skript ordnungsgemäß dämonisieren?

Auszuführendes Skript:

# 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-Skript:

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

Letzte ~ 20 Zeilen der Ausführung mit 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
quelle
Es scheint mir nützlich, dass Sie dieses Skript durchlaufen bash -vx ...und die letzten Zeilen posten, damit wir sehen können, was im Vordergrund bleibt.
Hauke ​​Laging
1
Machen Sie sich nicht die Mühe, diese Funktion richtig zu nutzen. Es daemongibt auch ein RPM-Paket . Übrigens, es gibt viele Tools zur Protokollüberwachung ( hier starten ).
Sr_
Hauke, meinst du eine erste Zeile von #!/bin/bash -vx? Ich habe versucht, dies zu tun, aber es wurde nicht die gleiche Ausgabe vom Init-Skript erzeugt, wie wenn ich das Shell-Skript direkt ausführen würde.
bshacklett
@bshacklett Sie können die Funktion eines beliebigen Init-Skripts (tatsächlich eines beliebigen Shell-Skripts) untersuchen, indem Sie es explizit mit ausführen bash -vx, z. bash -vx /etc/init.d/script start.
Sr_
1
@bshacklett Wrt logs, ich würde mir logstash genauer ansehen . Der Speicher kann direkt von Log4j aus mit Protokollen gespeist werden, der Logstash-Agent kann jedoch auch Protokolldateien überwachen
sr_ 21.04.13

Antworten:

2

Ich habe unter http://www.linuxforums.org/forum/programming-scripting/190279-daemon-etc-init-d-functions-does-not-return-launching-process.html#post897522 ein Skript gefunden, das ich ausführen konnte an meine Bedürfnisse anzupassen. Es verfolgt die PID manuell und erstellt eine PID-Datei mit pidof. Ich musste dies ändern, um es zu verwendenpgrep da pidofdie PID meines Skripts nicht angezeigt werden konnte. Nach dieser Änderung hat es gut funktioniert. * Hinweis: pgrep scheint nur zu funktionieren, wenn der vollständige Skriptname weniger als 15 Zeichen lang ist

Folgendes ist mir eingefallen:

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

Ich kenne Redhat nicht, sehe aber daemon $prog &seltsam aus. Wenn es bereits eine Funktion zum Daemonisieren gibt, warum sollte es notwendig (und nützlich) sein, diese Funktion selbst in den Hintergrund zu stellen? Also ohne die probieren &.

Hauke ​​Laging
quelle
4
Es ist nicht falsch /etc/init.d/functionsdefiniert eine daemonFunktion, die erwartet, dass ihr Argument sich selbst dämonisiert, es kümmert sich nur um Dinge wie das Ändern des Benutzers, das Setzen von Ulimits, das Prüfen (nicht das Erstellen!) einer Pid-Datei ... Die beste Verwendung dieser daemonFunktion ist es, sie durch libslacksdaemon zu ersetzen ;)
Sr_
Es tut mir leid, das & war da, als ich die Fehlerbehebung durchführte. Ich wollte es nicht in diesen Beitrag aufnehmen.
bshacklett