I am using an init script to run a simple process, which is started with:
start-stop-daemon --start --quiet --chuid $DAEMONUSER \
--make-pidfile --pidfile $PIDFILE --background \
--exec $DAEMON $DAEMON_ARGS
The process called $DAEMON usually prints log information to its standard output. As far as I can tell this data is not being stored anywhere.
I would like to write or append the stdout of $DAEMON to a file somewhere.
The only solution I know is to tell start-stop-daemon to call a shellscript instead of $DAEMON directly; the script then calls $DAEMON and writes to the logfile. But that requires an extra script which, like modifying the daemon itself, seems the wrong way to solve such a common task.
It is not too hard to capture daemon's output and save it to file:
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:To make it work we need a wrapper that terminates its children upon receiving
duende:SIGTERM
fromstart-stop-daemon
. There are some:Note:
uid=65534
is a usernobody
.Pros: it works and it is relatively easy.
daemon: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.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.pipexec (the winner):
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.
Assuming it's bash (although some other shells may allow this as well), the line:
will send all future standard output to that file. That's because
exec
without a program name just does some redirection magic. From thebash
man page:Management of said file is another issue of course.
To expand on ypocat's answer, since it won't let me comment:
Using
exec
to run the daemon allows stop to correctly stop the child process instead of just the bash parent.Using
--startas
instead of--exec
ensures that the process will be correctly detected by its pid and won't erroneously start multiple instances of the daemon if start is called multiple times. Otherwise, start-stop-daemon will look for a /bin/bash process and ignore the actual child process running the daemon.With openrc (which is the default on gentoo or alpine linux for instance)
start-stop-daemon
has the-1
and-2
options:So you can just write: