It is not too hard to capture daemon's output and save it to file:
start-stop-daemon --start --background \
--pidfile $PIDFILE --make-pidfile \
--chuid $DAEMON_USER \
--startas $DAEMON --no-close \
-- $DAEMON_ARGS >> $LOGFILE 2>&1
However this solution may be suboptimal for logrotate
.
It might be better to capture output to syslog. On Debian this would match behaviour of systemd services.
The following straightforward attempt to rewrite the above example is wrong because it leaves behind two parent-less ("zombie") processes (logger and daemon) after stopping the daemon because start-stop-daemon
terminates only its child but not all descendants:
## Do not use this!
start-stop-daemon --start --background \
--pidfile $PIDFILE --make-pidfile \
--chuid $DAEMON_USER \
--startas /bin/sh \
-- -c """exec $DAEMON $DAEMON_ARGS | /usr/bin/logger --tag $NAME"""
To make it work we need a wrapper that terminates its children upon receiving SIGTERM
from start-stop-daemon
. There are some:
duende:
start-stop-daemon --start --background \
--pidfile $PIDFILE \
--startas /usr/sbin/duende \
-- --pid $PIDFILE --chroot=/ --uid 65534 --ident $NAME \
/bin/su --login $DAEMON_USER --shell /bin/sh --command """exec ${DAEMON} $DAEMON_ARGS"""
Note: uid=65534
is a user nobody
.
Pros: it works and it is relatively easy.
Cons: 4 processes (supervisor duende
, its fork with dropped privileges (logger), su
and daemon itself); mandatory --chroot
;
If daemon terminates right away (e.g. invalid command) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
report it as started successfully.
daemon:
start-stop-daemon --start --pidfile $PIDFILE \
--startas /usr/bin/daemon \
-- --noconfig --name $NAME --stderr=syslog.info --stdout=syslog.info \
-- /bin/su --login $DAEMON_USER --shell /bin/sh --command """exec $DAEMON $DAEMON_ARGS"""
Pros: 3 processes (supervisor daemon
, su
and daemon itself).
Cons: Difficult to manage $PIDFILE
due to confusing daemon's command line options;
If daemon terminates right away (e.g. invalid command) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
report it as started successfully.
start-stop-daemon --start --background \
--pidfile $PIDFILE --make-pidfile \
--chuid $DAEMON_USER \
--startas /usr/bin/pipexec -- -k \
-- [ D $DAEMON $DAEMON_ARGS ] [ L /usr/bin/logger --tag $NAME ] '{D:2>D:1}' '{D:1>L:0}'
Pros: 3 processes (supervisor pipexec
, logger
and daemon itself); If daemon terminates right away (e.g. invalid command) status_of_proc -p $PIDFILE "$DAEMON" "$NAME"
correctly report failure.
Cons: none.
This is the winner -- the easiest, neat solution that seems to be working well.