How would a Bash (or other POSIX shell) command like this have to be expressed in fish?
ls -l $(which vim) # or
ls -l `which vim`
In fish
, $
is used only for variable expansion. Omit the $
from the command and you should be good. Say:
ls -l (which vim)
You might also want to refer to the documentation: Command Substitutions
As of Fish version 3.4.0, command substitution may now be done with either $()
or ()
grouping. E.g.:
ls -l $(which vim) # or
ls -l (which vim)
For versions prior to 3.4.0, only the ()
form is available.
Backticks, which do work in Bash and other POSIX shells, are not available as a command substitution operator. In general, backticks are no longer recommended in any shell for this purpose, but some habits (and old documentation) are hard to break.
which vim
returns the path to vim
as text that the ls -l
command can then process. If want to actually evaluate the text results in the shell itself, you'd need to eval $(which vim) --version
. However, that has exactly the same result as vim --version
, so why would you want to do it in the first place?
Commented
Jul 27, 2023 at 12:10
command vim --version
. That will make sure to call the command (rather than an alias or function).
Commented
Jul 27, 2023 at 12:11
Sometimes you need to use string split
inside ()
, otherwise -lgio-2.0 -lgobject-2.0 -lglib-2.0
will be incorrectly interpreted by the compiler as "go find a library named gio-2.0 -lgobject-2.0 -lglib-2.0
, with the spaces being part of its name".
To quote the official tutorial
Unlike other shells, fish does not split command substitutions on any whitespace (like spaces or tabs), only newlines. This can be an issue with commands like
pkg-config
that print what is meant to be multiple arguments on a single line. To split it on spaces too, usestring split
.> printf '%s\n' (pkg-config --libs gio-2.0) -lgio-2.0 -lgobject-2.0 -lglib-2.0 > printf '%s\n' (pkg-config --libs gio-2.0 | string split " ") -lgio-2.0 -lgobject-2.0 -lglib-2.0 ```