Is there a way to redirect output of a command that never stops to a file but only create the file once the command actually produces output?
Here is what I have so far:
target=logs/$(date +%Y%m%dT%H%M%S).mqtt
mosquitto_sub -v -t "#" --qos 0 >> $target
But this produces an empty file if no messages are sent to mosquitto
(hence mosquitto_sub
produces no output). I don't want that empty file.
I have two constraints:
- my system experiences sudden power cuts during normal operation and
- the log files are synced across the network all the time.
This is on a Raspberry Pi 4.
Therefore I need a solution that
- never creates an empty file (deleting it later is not an option) and
- starts writing the file without significant delay after
mosquitto_sub
starts writing to stdout.
Edit
Combining the solutions suggested by both duplicate targets still results in buffering:
stdbuf -oL -eL mosquitto_sub -v -t "#" --qos 0 | ifne tee $target
The file $target
is created as soon as mosquitto_sub results in output (i.e. as soon as a message is sent to mosquitto with mosquitto_pub
) but it remains empty until the buffer fills up, then lots of messages appear at once. Such a system would risk too much data loss in case of a power cut.
Applying stdbuf
to ifne
doesn't help either. The alternative unbuffer
doesn't even install successfully on my test system which is Linux Mint.
ifne tee "$target"
should work fine for thisifne tee
) do not work for a command likemosquitto_sub
that usually never stops. The last condition of my Q is not fulfilled: the file is written with infinite delay.mosquitto_sub
never stopping is a red herring,tee
works just fine with a never-ending input (try with, sayyes | tee foo
if you want). Your problem is more likely thatmosquitto_sub
starts buffering output when output is to a pipe, and the buffer takes a long time to fill up. Try turning off the buffering withstdbuf
orunbuffer
, e.g. stackoverflow.com/q/11337041/2072269, unix.stackexchange.com/q/25372/70524