Isso é dependente do shell e não é documentado pelo AFAICS. Em ksh e bash , no primeiro caso, foo compartilhará o mesmo status como bar . Eles lutarão pela saída de echo .
Então, por exemplo, em
$ seq 10000 | paste - <(tr 1 X)'
1 X
2 X042
3 X043
4 X044
5 X045
[...]
Você vê evidências de que paste lê todos os outros blocos de texto da saída de seq , enquanto tr lê os outros.
Com zsh , ele obtém o stdin externo (a menos que seja um terminal e o shell não seja interativo; nesse caso, ele é redirecionado de /dev/null ). ksh (onde se originou), zsh e bash são as únicas estruturas semelhantes a Bourne com suporte para substituição de processo AFAIK.
Em echo "bla" | bar < <(foo) , observe que o stdin de bar será o pipe alimentado pela saída de foo . Esse é um comportamento bem definido. Nesse caso, parece que o stdin de foo é o pipe alimentado por echo em todos os ksh , zsh e bash .
Se você deseja ter um comportamento consistente em todos os três shells e ser à prova do futuro, já que o comportamento pode mudar, pois não está documentado, eu o escreveria:
echo bla | { bar <(foo); }
Para ter certeza que o stdin de foo também é o canal de echo (não vejo por que você gostaria de fazer isso). Ou:
echo bla | bar <(foo < /dev/null)
Para garantir que foo não leia não do canal de echo . Ou:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
Para que foo inclua o stdin externo como nas versões atuais de zsh .