1

This question already has an answer here:

I want to get only the number of ms from a ping command to a file Without piping to a file it works as intended. I'm a little bit lost on why > to a file does not write anything.

This works:

ping 192.168.1.1 |egrep --line-buffered -v 'PING|timeout' |sed -l -e 's/^.* time=\(.*\) ms$/\1/g'

This does not write anything to ping.dat

ping 192.168.1.1 |egrep --line-buffered -v 'PING|timeout' |sed -l -e 's/^.* time=\(.*\) ms$/\1/g' > ping.dat

What am I doing wrong?

marked as duplicate by Jeff Schaller, Rui F Ribeiro, Jakuje, Archemar, don_crissti Feb 16 '16 at 16:48

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2

Each | is potentially surrounded by an stdio output buffer and an stdin input buffer. You need to find out which of those you need to turn off to get realtime piping.

This works for me:

ping localhost |egrep --line-buffered -v 'PING|timeout' |\
stdbuf -o0 sed -l -e 's/^.* time=\(.*\) ms$/\1/g' > file

Initially I had put stdbuf -i0 -o0 before every command and then found out which were unnecessary.

  • Doesn't the --line-buffered with egrep solve this? Or does grep's output then also get buffered? – Otheus Feb 16 '16 at 13:56
  • 1
    @Otheus Since stdbuf -o0 does solve the problem, it appears sed uses stdio and the stream gets stuck in its stdout's output buffer. – PSkocik Feb 16 '16 at 14:04
  • Oh I see! OK, I confirmed GNU sed's -u also does this. – Otheus Feb 16 '16 at 14:22
0

If you're using GNU, then it appears the -l option to sed is incorrect: you probably want the -u (unbuffered) option. Also, the grep is superfluous. You should be able to get what you want from just the sed:

ping $HOST | sed -u -n '/ ms$/s/.* time=\(.*\) ms$/\1/p' >file.out

The -n suppresses normal matching output, while the s///p forces the output of matching lines.

Not the answer you're looking for? Browse other questions tagged or ask your own question.