In sh:
~$ `echo ls`
bin/ Desktop/
But in fish:
fish: Illegal command name “(echo ls)”
~% (echo ls)
(Note that the error message appears above the command line.)
~% echo (echo ls)
ls
~% eval (echo ls)
bin/ Desktop/
fish: Illegal command name “(echo ls)”
exec (echo ls)
^
~% exec (echo ls)
It seems that command substitution only works as parameters of a command, not as a command itself? Why?
Well, the help doc does say
If a parameter contains a set of parenthesis, the text enclosed by the parenthesis will be interpreted as a list of commands.
But still, why?
Update
This answer was written ten year ago in 2010.
Recent versions of fish (I tested on 3.1.2) updated and
set cmd ls; $cmdis valid now.How
This because command substitutions belong to parameter expansions and are not allowed as commands.
A similar example:
in sh:
But in fish:
Why
In short, it’s good for verifiability
This article explains details:
For the same reason, command substitutions are not allowed as commands.
(Note: The cited example is not fair, since ‘if’ and ‘fi’ are not simple commands but reserved words. See comments below.)