Read from a pipe, write to a file
If you want the daemon to read input produced by some arbitrary process, you need to connect that process to a pipe. Here the arbitrary process is you echoing commands, and it's going to run in a different context. So create a named pipe (often called a fifo in unix contexts).
mkfifo /var/run/daemon.fifo
</var/run/daemon.fifo /path/to/daemond --option >daemon.log
And just write commands to the pipe:
echo 'FORWARD 10' >/var/run/daemon.fifo
echo 'LEFT 72' >/var/run/daemon.fifo
This is unlikely to work as is however: there's a good chance that the daemon will exit when it sees an end of file on its standard input, which happens as soon as the first process that writes to the pipe terminates. You can use tail -f
to avoid that problem.
</var/run/daemon.fifo tail -c +1 -f | {
echo $$ >/var/run/daemon.pid
exec /path/to/daemond --option >daemon.log
}
With some tail
implementations, you may get bitten by buffering: the tail
process will wait until it has amassed enough bytes to emit some output. I don't think this is solvable in the POSIX toolbox; if that's a problem, use a trivial C or Perl or Python program. As far as I can tell the tail
from GNU coreutils (as found on Linux and elsewhere) is safe on this respect.
When you stop the daemon, echo >/var/run/daemon.fifo
will kill the tail
process.
Starting the program inside screen
Instead of invoking the daemon directly from your service manager (are you really using just SysV init, or something additional like wrapper scripts or Upstart?), invoke
screen -c daemon.screenrc -L -d -m -S daemon_name /path/to/daemond --option
Since the daemon won't be a child process of the service manager, you need to make sure to send a signal to the right process. How to do that depends on exactly how the daemon is started and by what.
It's technically possible to attach a running process to a terminal, but there's a risk you'll crash the program, so this is definitely out for a production system.
The -L
option makes screen write everything that appears in its window to a file. The file name is given in daemon.screenrc
with the logfile
directive.