Process substitution is a feature that originated in the Korn shell in the 80s (first documented in ksh86). At the time, it was only available on systems that had support for /dev/fd/<n> files.
Later, the feature was added to zsh (from the start: 1990) and bash (in 1993). zsh was using temporary named pipes to implement it, while bash was using /dev/fd/<n> where available and named pipes otherwise. zsh switched to using /dev/fd/<n> where available in 2.6-beta17 in 1996.
Support for process substitution via named pipes on systems without /dev/fd was only added to ksh in ksh93u+ in 2012. The public domain clone of ksh doesn't support it.
To my knowledge, no other Bourne-like shell supports it (rc, es, fish, non-Bourne-like shells support it but with a different syntax). yash has a <(...) construct, but that's for process redirection.
While quite useful, the feature was never standardized by POSIX. So, one can't expect to find it in sh, so shouldn't use it in a sh script.
Though the behaviour for <(...) is unspecified in POSIX, (so there would be no harm in retaining it), bash disables the feature when called as sh or when called with POSIXLY_CORRECT=1 in its environment.
So, if you have a script that uses <(...), you should use a shell that supports the feature to interpret it like zsh, bash or AT&T ksh (of course, you need to make sure the rest of the syntax of the script is also compatible with that shell).
In any case:
cat <(cmd)
Can be written:
cmd | cat
Or just
cmd
For a command other than cat (that needs to be passed data via a file given as argument), on systems with /dev/fd/x, you can always do:
something | that-cmd /dev/stdin
Or if you need that-cmd's stdin to be preserved:
{ something 3<&- | that-cmd /dev/fd/4 4<&0 <&3 3<&-; } 3<&0
Where 3<&0 duplicates fd 0 onto fd 3 for the whole {...} command group so as to make the corresponding resource it's opened on available to that-cmd.
In the pipeline in that command group, we close that fd 3 with 3<&- for the left hand side (something) as it doesn't need it, and for the right hand side (that-cmd):
- with
4<&0 we copy fd 0 (the reading end of the pipe) to fd 4, so that-cmd can open the pipe on /dev/fd/4 - then move (copy + close) fd 3 (our original stdin) to fd 0, so
that-cmd's stdin is the original stdin (the one of the command group).
bash -c "cat <(echo 'Hello')". If you're using Debian/Ubuntu, you most likely havedashas your/bin/sh. see: lwn.net/Articles/343924shis linked tobash, when invoked asshit operates in "POSIX mode" and wouldn't support that featurebashdisables<(...)when invoked assh.