Muszę zainstalować program jako usługę w Red Hat. Nie stanowi tła, nie zarządza plikiem PID ani nie zarządza własnymi dziennikami. Po prostu działa i drukuje do STDOUT i STDERR.
Używając standardowych skryptów inicjujących jako przewodników, opracowałem:
#!/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
Być może moim błędem było skopiowanie-wklejenie i zmodyfikowanie niektórych istniejących skryptów w /etc/init.d. W każdym razie wynikowa usługa zachowuje się dziwnie:
- kiedy go uruchamiam,
service someprog start
program drukuje na terminalu, a polecenie nie kończy się. - jeśli I CTRL-C, wyświetli „Sesja zakończona, zabijanie powłoki ... ... zabite. NIEUDANE”. Muszę to zrobić, aby ponownie wyświetlić monit powłoki.
- teraz, kiedy uruchamiam
service someprog status
, mówi, że działa i wyświetla swój PID. Widzę to,ps
więc działa. - teraz kiedy uruchamiam
service someprog stop
, nie przestaje. Mogę sprawdzić, czy nadal działaps
.
Co muszę zmienić, aby someprog
zostało wysłane w tle i zarządzane jako usługa?
Edycja: Znalazłem teraz kilka powiązanych pytań, z których żadne nie ma rzeczywistej odpowiedzi innej niż „zrób coś innego”:
- Wywołanie demona w skrypcie /etc/init.d jest blokowane, nie działa w tle
- Uruchamianie skryptu powłoki jako demona w CentOS?
Edycja: ta odpowiedź przy podwójnym rozwidleniu mogła rozwiązać mój problem, ale teraz mój program podwójnie rozwidla i to działa: https://stackoverflow.com/a/9646251/898699
Odpowiedzi:
Polecenie „nie zostało ukończone”, ponieważ
daemon
funkcja nie uruchamia aplikacji w tle. Musisz dodać&
na końcudaemon
polecenia w następujący sposób:daemon --user someproguser $exec &
Jeśli
someprog
nie obsługujeSIGHUP
, powinieneś uruchomić polecenie z,nohup
aby upewnić się, że proces nie odbierze,SIGHUP
co każe procesowi zakończyć działanie po wyjściu powłoki nadrzędnej. To by wyglądało tak:daemon --user someproguser "nohup $exec" &
W twojej
stop
funkcjikillproc "exec"
nic nie robisz, aby zatrzymać twój program. Powinno to brzmieć tak:killproc $exec
killproc
wymaga pełnej ścieżki do Twojej aplikacji, aby ją poprawnie zatrzymać. W przeszłości miałem pewne problemykillproc
, więc możesz po prostu zabić PID w pliku PIDFILE, do którego powinieneś pisaćsomeprog
PID za pomocą czegoś takiego:cat $pidfile | xargs kill
Możesz zapisać plik PIDFILE w następujący sposób:
ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile
gdzie
$pidfile
wskazuje/var/run/someprog.pid
.Jeśli chcesz [OK] lub [FAILED] w swojej
stop
funkcji, powinieneś użyć funkcjisuccess
ifailure
z/etc/rc.d/init.d/functions
. Nie potrzebujesz ich wstart
funkcji, ponieważdaemon
wywołuje odpowiednią dla Ciebie.Potrzebujesz także tylko cudzysłowu wokół ciągów ze spacjami. Jest to jednak wybór stylu, więc to zależy od Ciebie.
Wszystkie te zmiany wyglądają następująco:
źródło
Jeśli to twój program, napisz go jako właściwego demona. Zwłaszcza jeśli chodzi o redystrybucję. :)
Możesz spróbować monitorować . A może coś takiego jak runit lub daemontools. Te potężne nie mają łatwo dostępnych pakietów. Daemontools pochodzi od DJB, jeśli ma to wpływ na twoją decyzję (w dowolnym kierunku).
źródło
Zrobiłem trochę więcej badań i wydaje się, że odpowiedź brzmi „nie możesz tego zrobić”. Program, który ma zostać uruchomiony, musi się właściwie właściwie zdemonizować: rozwidlić i odłączyć swoje standardowe uchwyty plików, odłączyć od terminala i rozpocząć nową sesję.
Edycja: najwyraźniej się mylę - podwójne rozwidlenie działałoby. https://stackoverflow.com/a/9646251/898699
źródło