As I understand the bash documentation both | and < redirect stdin. So, cmd | foo and foo < <(cmd) should be more or less equivalent. However, for the bash-internal read command this doesn't seem to be the case. E.g., if I enter

a=""; b=""; read a b < <(echo a b); echo $a $b

it prints out a b, while

a=""; b=""; echo a b | read a b; echo $a $b

prints out nothing. On the other hand, if I enter

a=""; b=""; cat < <(echo a b) >foo1

a=""; b=""; echo a b | cat > foo2

the files foo1 and foo2 are exactly the same. So my question is: what is the difference with both forms when the read command is involved (or in general)? They should see exactly the same redirected input. While the < <(...) form works, I find it pretty unreadable and would much prefer to use the pipe form.


1 Answer 1


The act of pipelining executes read in a subshell, whereas process substitution does not. For most use cases, this isn't a problem, but in this instance you want to directly affect the shell (by manipulating variables). Because read has been invoked in a subshell, only the subshell is affected. As such, any actions that you might wish to perform on them will need to also be performed in the subshell; for example:

echo a b | { read a b ; echo "$a" "$b" ; }
  • Yeah, thanks a lot. I didn't think about this subshell issue before, but this clears up everything. I also found [tldp.org/LDP/abs/html/gotchas.html#BADREAD](this) now in the Advanced Bash Scripting Guide. They recommend using the [tldp.org/LDP/abs/html/internal.html#SETPOS](set) command instead, to assign the values to the positional parameters. Mar 12, 2012 at 9:26
  • 2
    @ElmarZander - Don't use the infamous "Advanced" Bash Scripting guide from TLDP, it will teach you to write bugs, not scripts. There are places where it is badly written, and many more places where it is simply flat out wrong. I'd recommend BashGuide instead.
    – Chris Down
    Mar 12, 2012 at 11:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .