I want to monitor the realtime output of a program that I will start. I am trying to do this by redirecting the output of the program to a pipe and then reading the pipe from a monitoring script.
./program >> apipe
then from the monitoring script
cat apipe
However due to the buffer in >> there is no output. Anyway I can disable this buffer? I am running on a barebones embedded system (petalinux) so I don't have access to unbuffer, script, or stdbuf to help me out.
I have tried the scripts on another platform where unbuffer is available it works as I expect.
Any way I can configure this buffer, or use another binary to redirect?
Edit: I do not have access to the source code of the command I am trying to run. It is a legacy binary.
If you don't have access to
stdbuf
, you might as well simulate it and unbuffer thestdout
manually withgdb
(assuming obviously you have access togdb
).Let's take a look at how
stdbuf
actually operates. Thestdbuf
GNU coreutils command basically only injectslibstdbuf
in the user program by settingLD_PRELOAD
environment variable. (Irrelevant, but for the record, options are passed via_STDBUF_E
/_STDBUF_I
/_STDBUF_O
env vars.)Then, when the
libstdbuf
is run, it callssetvbuf
libc function (which in turn executes the underlaying syscall) on appropriate file descriptors (stdin
/stdout
/stderr
), with the appropriate mode (fully buffered, line buffered, or unbuffered).Declaration for
setvbuf
is instdio.h
, available withman 3 setvbuf
:Values for
mode
are:_IONBF
,_IOLBF
,_IOFBF
, as defined instdio.h
. We are here only interested in the unbuffered mode:_IONBF
. It has a value of2
(you can check your/usr/include/stdio.h
).Unbuffer script
So, to unbuffer a
stdout
for some process, we just need to call:We can easily do that with
gdb
. Let's make a script we can call,unbuffer-stdout.sh
:Then, we can call it like:
(You'll probably need
sudo
to run it asroot
.)Testing
We can use this simple Python program with buffered standard output (if not called with
-u
, and with unsetPYTHONUNBUFFERED
),writer.py
:Run it with:
and observe no output appears until we run: