19

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`
NotTheDr01ds
  • 28,025
Raffael
  • 1,251

3 Answers3

23

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

Paul Irish
  • 1,105
devnull
  • 3,405
2

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.

NotTheDr01ds
  • 28,025
1

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, use string 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 ```
nalzok
  • 224