I'm not really sure even what is the subject, initially I was struggling with grep
with a suggestion the it is a root cause yet seems it is something related to pipes buffering or something
On Alpine Linux v3.18
using inotifyd
(fs changes tracking tool) in pipe produces a strange behavior
As a data source will be using same command inotifyd - /tmp:ymndceDM
together with serial call similar to echo 1 > /tmp/2.log
Running a normal call as
# inotifyd - /tmp:ymndceDM | xxd
00000000: 6309 2f74 6d70 0932 2e6c 6f67 0a63 092f c./tmp.2.log.c./
00000010: 746d 7009 322e 6c6f 670a 6309 2f74 6d70 tmp.2.log.c./tmp
00000020: 0932 2e6c 6f67 0a63 092f 746d 7009 322e .2.log.c./tmp.2.
00000030: 6c6f 670a 6309 2f74 6d70 0932 2e6c 6f67 log.c./tmp.2.log
00000040: 0a63 092f 746d 7009 322e 6c6f 670a 6309 .c./tmp.2.log.c.
00000050: 2f74 6d70 0932 2e6c 6f67 0a63 092f 746d /tmp.2.log.c./tm
# inotifyd - /tmp:ymndceDM | grep ''
c /tmp 2.log
c /tmp 2.log
c /tmp 2.log
c /tmp 2.log
produces pretty expected output
Yet if a pipeline is extended with extra commands an output stacks at a single line state as
# inotifyd - /tmp:ymndceDM | xxd | cat
00000000: 6309 2f74 6d70 0932 2e6c 6f67 0a63 092f c./tmp.2.log.c./
# inotifyd - /tmp:ymndceDM | grep '' | cat
c /tmp 2.log
regardless of serial incoming changes to subject file.
Using only cat
s instead of xxs
or grep
works fine as well
Taking separately output from inotifyd
into some log file and applying cat changes.log
to the same (initially problematic) pipeline doesn't give described problems.
So please how this could be explained and resolved?
Thx
Trying to turn buffering (as my second suspection) off found suggestion to run commands in separate groups as
{ inotifyd - /tmp:ymndceDM; } | { grep ''; } | { cat; }
but that didn't really help
Edited:
Thanks to @programmerq answer bellow it turned out the buffering is the behavior of xxd
it self in case it is down-streamed to a non tty.
I confirmed as well the same for grep
. Actually trying
inotifyd - /tmp:ymndceDM \
| xargs -n 1 -I {} \
echo {} somenoicesomenoicesomenoicesomenoicesomenoicesomenoicesomenoicesomenoicesomenoicesomenoicesomenoicesomenoi \
| grep '' | cat
makes overflow the buffer each line and leads to a "realtime" output.
So the question now is how to disable buffering in more pure way?
--line-buffered
is not supported for alpine and no other available options seem to help.
In my particular case I can see another workaround to multiply incoming lines by some factor as anyway the is a uniq
below in the line. But this doesn't seem to be such a pretty solution. (e.g. Could the buffer size supposed to be constant)
Anyway is it possible maybe to fake grep
somehow (with minimal code overhead) to make it think it is feeded down to tty?
Or what could be the resolution here to get a realtime stream of updates regardless chunk size?
Thx.