Strange behavior with sed/head and named pipes/FIFOs (needs two writes)

I have a fifo created with mkfifo in a shell, opened in rw mode with exec 3<>fifo.

When I run sed 1q <&3 and write a line to the fifo in another shell, sed doesn’t print the line until
I write another line to the fifo. Why does this happen? (This doesn’t occur with head -n1)

Asked By: SeetheMoar

||

You can replicate that in one shell session with e.g.

(echo foo; sleep 3; echo bar) | busybox sed 1q

You’ll see the lone output line appear only after the delay.

What likely happens is that Busybox’s implementation continues reading before processing the first line to determine if the $ (last line) address specifier should match. Before the pipe closes, or it sees a second line appear, it can’t determine which way $ should resolve.

This doesn’t happen with all seds, e.g. GNU sed and the sed on my Mac print the first line immediately. Which they can do, since the script doesn’t use $, so all information required is already there. If you change the script to something using $, e.g.

(echo foo; sleep 3; echo bar) | sed -n '$!p'

they, too have to wait to get the second line.

Presumably Busybox is just being simpler and waits in any case, without bothering to check if $ is used.

Answered By: ilkkachu
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.