Bash – Pipe Fail (141) When Piping Output into Tee

bashtee

An example should clarify my question. This behavior makes sense to me:

$ echo hi | cat
hi
$ echo hi | tee >(cat)
hi
hi

The first case is obvious. In the 2nd case, we pipe "hi" into tee using command substitution, and one "hi" is printed by the tee'd cat, while another is printed by tee's pass through pipe. So far, so good…

But what happens to the first "hi" in this case:

$ echo hi | tee >(echo yo)
yo

The return code is 141, a pipe fail. What could be causing this?

I'm running Mac OSX El Capitain, bash in default terminal app

Best Answer

I think I’ve figured out how to tweak your experience to turn it into something other people will be able to reproduce:

$ (echo hello; sleep 1; echo world) | tee >(cat)
hello
hello                                                       … and, after a brief delay,
world
world

$ echo "$?"
0

$ (echo hello; sleep 1; echo world) | tee >(echo yo)
yo
hello

$ echo "$?"
141

As you hopefully understand, >(command) creates a pipe to a process running command.  The standard input of command is connected to a pathname that other commands on the command line (in this case, tee) can open and write to.  When command is cat, the process sits there and reads from stdin until it gets an EOF.  In this case, tee has no problem writing all the data it reads from its stdin to the pipe.

But, when command is echo yo, the process writes yo to the stdout and immediately exits.  This causes a problem for tee; when it writes to a pipe with no process at the other end, it gets a SIGPIPE signal.

Apparently OS X’s version of tee writes to the file(s) on the command line first, and then its stdout.  So, in your example (echo hi | tee >(echo yo)), tee gets the pipe failure on its very first write.  Whereas, the version of tee on Linux and Cygwin writes to the stdout first, so it manages to write hi to the screen before it dies.  In my enhanced example, tee dies when it writes hello to the pipe, so it doesn’t get a chance to read and write world.

Related Question