Because that's how it's meant to be.
<(...)
in bash
is the syntax for process substitution. It's copied from the same operator in ksh
.
<
, (
, )
, |
, &
, ;
are special lexical tokens in bash
that are used to form special operators in different combinations. <
, <(
, <<
, <&
... each have their role. <
is for redirection. <file
, < file
would redirect input from a file. <'(file)'
would redirect input from a file called (file)
, but <(file)
is a different operator that is not a redirection operator.
< (file)
would be <
followed by (file)
. In that context, in bash
, (file)
is not valid. (...)
can be valid as a single token in some contexts like:
(sub shell)
func () {
...
}
var=(foo bar)
But not in
sort < (cmd)
In the fish
shell, it's different. In fish
, (...)
is for command substitution (the equivalent of $(...)
in bash
). And <
is for input redirection like in Bourne-like shells.
So in fish
:
sort <(echo file)
would be the same as:
sort < (echo file)
That is:
sort < file
But that's something completely different from bash
's process substitution.
In the yash
shell, another POSIX shell, <(...)
is not for process substitution but for process redirection
In there,
sort <(ls -l)
Short for:
sort 0<(ls -l)
is a redirection operator. It's more or less equivalent to:
ls -l | sort
While in bash
, the <(ls -l)
is expanded to the path of a pipe, so it's more like:
ls -l | sort /dev/fd/0
In zsh
, (...)
is overloaded as a globbing operator ((*.txt|*.png)
would expand to txt
and png
files) and as glob qualifier (*(/)
for instance expands to directory files).
In zsh
, in:
sort < (ls -l)
That (ls -l)
would be treated as a glob qualifier. The l
glob qualifier is to match on number of links and expects a number after l
(as in ls -ld ./*(l2)
would list the files with 2 links), so that's why you get a zsh: number expected
error there.
sort < (w)
would have given a zsh: no matches found: (w)
error instead as (w)
matches the files with empty name that are writeable.
sort < (w|cat)
would have sorted the content of the w
and/or cat
files in the current directory...