I did not get the mkfifo
trick to work satisfactorily; it did not seem to capture stderr, and attempts to redirect caused Upstart to bail with no errors.
It also has an unfortunate side effect of making the logger
process hang around as a child of init
, so the information about who "owns" the logger is lost, and anyone not already aware of the mkfifo
might assume it's a dangling process that can be killed.
Instead I ended up with the following solution, which resolves all of these issues. It causes logger
to become a child process, while preserving the service as the root process. Unfortunately, it requires exec'ing bash
, but it just looks dirty.
script
# ... setup commands here, e.g. environment, cd, ...
exec bash <<EOT
exec 1> >(logger -t myservice) 2>&1
exec myservice
EOT
end script
This uses a trick that redirects stdout and stderr to a command. Since we exec the service inside the bash
command, this has the side effect of replacing the shell and magically making bash become a child process of the service, as shown by ps aufxw
:
myservice
\_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice
\_ logger -t myservice
For some reason the above command has to be wrapped in a bash -c
. I assume this is because Upstart only pretends to run your script via Bash, but isn't actually. If anyone can suggest a way to avoid the extra bash shell, that would be awesome.