Pipe – Process Each Line of Ping Output Immediately

pipe

I have a few examples of different ways of extracting timing information from ping -c 10 google.com. For some of these pipelines, a line of output is produces every so often, just like the output of ping. For others, the lines of output are emitted all at once at after all of them have been processed. Is there a good rule for when I'll see the first behavior and when I'll see the second?

# prints output for each line as soon as it is received
# on OS X and Linux.
ping -c 10 google.com | grep -o 'time=\S*'

# prints output for each line as soon as it is received on OS X
# but not on Linux 
# (the output of ping is slightly different so it's $8 on Linux to get the time)
ping -c 10 google.com | awk '{ print $7 }'

# waits until all input is received on OS X and Linux
ping -c 10 google.com | awk -F ':' '{ print $2 }'

# prints output for line as soon as it is received on Linux and OS X
ping -c 10 google.com | sed -e 's/^.*time=\(.*\) .*$/\1/'

# waits for the end of input on OS X and Linux
ping -c 10 google.com | grep -o 'time\S*' | sed -e 's/time=//'

# as a quick check, this prints each line of output immediately 
# on OS X and Linux
ping -c 10 google.com | sed -e 's/time=//' 

After looking around for a little bit, this seems to be just an issue of line buffering and some of the standard utilities behaving differently when used interactively vs non-interactively.

Best Answer

It's about how buffering is handled with those programs.

If you want grep to output piped data immediately, use it with option --line-buffered.

ping -c 10 google.com | grep --line-buffered -o 'time\S*' | sed -e 's/time=//'

If you want awk to output piped data immediately, you can use option -W interactive.

ping -c 10 google.com | awk -W interactive '{ print $7 }'

You should read man pages for those apps to find out more.

Related Question