Multiple unix pipes not working

This first pipeline works fine (printing "c"):

echo "a" | sed 's/a/b/' | sed 's/b/c/'

This one does not do what I expect (nothing gets printed when I feed an "a" into my fifo ):

mkfifo fifo;
cat fifo | sed 's/a/b/' | sed 's/b/c/' 

However, if I remove the second "sed" command from the latter pipeline, I do get a "b" printed. I think my understanding of pipes and redirects must be too simplistic. Can someone explain to me how to fix the 2nd case so that I can run two successive commands on the contents of the fifo?

(note this isn't a problem specific to fifo, the same behavior occurs with netcat too. I posted a similar question about netcat but got no answers)


Solution 1:

Use the -u (--unbuffered) option of sed, so it writes it's output, instead of collecting it first for a fast, large write later.

cat fifo | sed -u 's/a/b/' | sed -u 's/b/c/'

cat is always unbuffered.

If it's not about sed, but some program with output buffering, but without options to disable it, there are tools that can help to force buffering off - see man unbuffer and man stdbuf.

If it's a shell script, it should be unbuffered by default: when a command creates output in the script, and exits, the output is flushed. Otherwise, you use unbuffer inside the shell script.

For background, see this overview of stdio buffering.