I like to log a programs output ‘on demand’. Eg. the output is logged to the terminal, but another process can hook on the current output at any time.
The classic way would be:
myprogram 2>&1 | tee /tmp/mylog
and on demand
tail /tmp/mylog
However, this would create a ever growing log file even if not used until the drive runs out of space. So my attempt was:
mkfifo /tmp/mylog
myprogram 2>&1 | tee /tmp/mylog
and on demand
cat /tmp/mylog
Now I can read /tmp/mylog at any time. However, any output blocks the program until the /tmp/mylog is read. I like the fifo to flush any incoming data not read back. How to do that?
Inspired by your question I’ve written a simple program that will let you do this:
$ myprogram 2>&1 | ftee /tmp/mylogIt behaves similarly to
teebut clones the stdin to stdout and to a named pipe (a requirement for now) without blocking. This means that if you want to log this way it may happen that you’re gonna lose your log data, but I guess it’s acceptable in your scenario.The trick is to block
SIGPIPEsignal and to ignore error on writing to a broken fifo. This sample may be optimized in various ways of course, but so far, it does the job I guess.You can compile it with this standard command:
$ gcc ftee.c -o fteeYou can quickly verify it by running e.g.:
$ ping www.google.com | ftee /tmp/mylog$ cat /tmp/mylogAlso note – this is no multiplexer. You can only have one process doing
$ cat /tmp/mylogat a time.