
Ich habe ein Shell-Skript, das im Wesentlichen ein Einzeiler mit einigen Protokollierungsfunktionen ist, und das ich von einem Init-Skript aus ausführen möchte. Ich verwende die daemon
darin enthaltene Funktion /etc/init.d/functions
, um es auszuführen, da Redhat diese anscheinend nicht start-stop-daemon
zur Verfügung hat. Wenn ich das Init-Skript () aufrufe, /etc/init.d/script start
bleibt es im Vordergrund, anstatt abgeschlossen zu werden und den Prozess weiterlaufen zu lassen. Wie kann ich dieses Skript richtig als Daemon ausführen?
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
Antwort1
Ich habe ein Skript gefunden beihttp://www.linuxforums.org/forum/programming-scripting/190279-daemon-etc-init-d-functions-does-not-return-launching-process.html#post897522die ich an meine Bedürfnisse anpassen konnte. Es verfolgt die PID manuell und erstellt eine PID-Datei mit pidof
. Ich musste dies schließlich ändern, um zu verwenden, pgrep
da pidof
ich die PID meines Skripts nicht sehen konnte. Nach dieser Änderung funktionierte es einwandfrei. *Hinweis: pgrep scheint nur zu funktionieren, wenn der vollständige Skriptname weniger als 15 Zeichen lang ist
Hier ist das Ergebnis:
#!/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 $?
Antwort2
Ich kenne Redhat nicht, aber daemon $prog &
es sieht für mich seltsam aus. Wenn es bereits eine Funktion zum Daemonisieren gibt, warum sollte es dann notwendig (und sinnvoll) sein, diese Funktion selbst in den Hintergrund zu stellen? Versuchen Sie es also ohne das &
.