I am using a tool (openocd
) which is printing a lot of garbage, then a basic progress bar slowly printing simple dots, then again some garbage.
I would like to filter this output with grep
so only the line with progress bar is shown, and in real time (i.e. each dot outputted by openocd
is immediately printed in the terminal):
openocd <args> |& grep '^\.'
The problem is that grep
is line buffered (at best) so the progress bar will not be shown until it is finished.
How can I do with grep
, or is there any standard alternative to achieve this?
If there is a way through openocd
configuration, this would be useful though I would prefer a more general solution.
Best Answer
This is a kind of hacky/unusual answer, the fact being that this is most likely possible in a not very clean way.
grep
itself seems to only print output when it encounters a newline character, your progress bar likely does not introduce a newline character when it updates, hence your issue.strace
is a tool used to view the system calls that a command is calling, this includes things like reading and writing things to memory/storage, as well as things like opening/closing file descriptors.With
strace
you can view what a process is accessing, in the case of your pipestout
is being passed togrep
, so withstrace
you can view the text that's being fed togrep
.strace
will regularly be sent the output coming from the piped command, and you can sniff that output and display it. I was testing withrsync --progress
, which seems to run into a similar scenario. I usedgrep
on the##%
because that's whatrsync
uses to show progress.If you run this command you'll find that
strace
doesn't have nice output, but that when I used itstrace
caught a couple ofread
s from thersync
thatgrep
would not normallywrite
, showingread
s for 0%, 21%, 45%, 68%, 91% and 100%, seemed to update about every second (probably based on how oftenrsync
updates the progress).So with that you can
grep
thestrace
output, which is not very nice, by calling the samegrep
again.The
2>&1
is important becausestrace
prints onstderr
. The> /dev/null
redirectsstdout
to/dev/null
to prevent the output of the firstgrep
being reported. The end result of this was the following output:You'll have to swap out the
grep
, but it seems like it'll do the trick. It's not pretty, but it functions, and works around the restrictions ofgrep
. Seems like agrep -f
that works liketail -f
would be handy (I knowgrep -f
is already in use).The first
grep
is mostly just to filter down the text thatstrace
will beread
ing, since only the matching lines will be listed instrace
sread
calls, but you also need something for the text to be moving through sostrace
can watch it.