I'm struggling with this problem. I have this line:
mplayer *.* 2>/dev/null | grep Playing
which just launchs mplayer
and only the line matching Playing filename
is printed on screen.
This works also every time I change currently played media.
I was wondering if it was possible to "format" the output of grep. For example, if the output is:
Playing Pink_Floyd-Wish_You_Were_Here.mp3 # I get this at the beginning
Playing Pearl_Jam-Once.mp3 # I get this after I change media inside mplayer
then I would have something like:
Mplayer: Playing Pink_Floyd-Wish_You_Were_Here.mp3
Mplayer: Playing Pearl_Jam-Once.mp3
To do so, I decided to employ awk:
mplayer *.* 2>/dev/null | grep Playing | awk '{print "Mplayer: "$1}'
But in this case nothing happens; I get no output!!!
My question is not oriented to solve the problem with mplayer, but to have a deeper understanding about pipes in bash.
For example, if I use the following:
echo a_song.mp3 | awk '{print "Mplayer: "$1}'
I get what I want
Mplayer: a_song.mp3
Why does the first command not work?
What do I have to do if I want to run more than one process like this in background?
Best Answer
Many grep implementation will use line buffered when standard output is terminal. When standard output is terminal, it's often an interactive session, you want to get data as soon as possible. So
grep
will write data to standard output as soon as seeing a newline.When standard output isn't terminal (often meaning non-interactive session),
grep
will use block buffer instead. It meansgrep
doesn't write to standard output immediately when seeing a newline.grep
collects amount of data (4096 bytes in Linux) before writing to standard output.Some
grep
version, like GNU grep or BSD grep have --line-buffered option. It makegrep
always writing to standard output when seeing a newline. So your example become:If your
grep
version doesn't have--line-buffer
, you can do it all withawk
:GNU coreutils has a tool stdbuf for modifying buffering of command. You can always force line buffer in standard output with:
There's also unbuffer command which disables the output buffering only.
Further reading