0

Trying to capture only the packets return time from ping output, I issued

$ ping 192.168.0.1 | grep -o '[^ =]* ms'

and it worked, displaying each packet time when it arrived. Since I also wanted to get rid of the unit of time, thought this would suffice:

$ ping 192.168.0.1 | grep -o '[^ =]* ms' | grep -o '^[^ ]*'

But, to my surprise, it hangs, showing no output. Replacing the first command with an echo of a sample line from ping output, however, works as expected (it outputs 5.07):

$ echo '64 bytes from 192.168.0.1: icmp_seq=10 ttl=64 time=5.07 ms' | grep -o '[^ =]* ms' | grep -o '^[^ ]*'

I found other means of getting only the time without the milissecond unit, but still: What is the issue with ping command? Why is passing it through one pipe is OK, but not through two?

PS: These below also fail, while their echo versions succeed, thus the problem can't be with grep

$ ping 192.168.0.1 | grep -o '[^ =]* ms' | sed 's_ ms__'
$ ping 192.168.0.1 | grep -o '[^ =]* ms' | cut -f 1 -d ' '
$ ping 192.168.0.1 | cut -f 7 -d ' ' | cut -f 2 -d '='
Quasímodo
  • 18,865
  • 4
  • 36
  • 73

2 Answers2

2

The definite answer is line buffering. You can demonstrate this with ping -c 3 instead of just ping, where all output is produced only at the completion of the first command.

As a workaround with GNU grep you can reduce your two filters to one

ping 192.168.0.1 | grep -oP '[[:digit:].]+(?= ms)'

Or if you really want to use two filters, either grep --line-buffered ... or stdbuf -oL grep ... will work for you.

Chris Davies
  • 116,213
  • 16
  • 160
  • 287
0

I think your problem is caused by the line buffering of your shell.

If you let your command run long enough, you should see some output.
Or just limit the amount of pings like this:

$ ping -c4 192.168.0.1 | grep -o '[^ =]* ms' | grep -o '^[^ ]*'

There is some more information and workarounds (solutions?) if you follow this link

bey0nd
  • 937