3
votes

Is it possible in Fish to perform command substitution in a way where I define the command to be treated as a single argument for commands like echo? In Bash it would be equivalent to e.g.:

$ echo "$(cat file.txt)"
lorem
ipsum

The approach suggested by Fish doesn't work for multi-line (or spaced) output:

$ echo (cat file.txt)
lorem ipsum

And if I add quotes, it doesn't perform the command substitution at all:

$ echo "(cat file.txt)"
(cat file.txt)
1

1 Answers

6
votes

Command substitution in bash returns a single string. If you echo the string unquoted, you are subject to word splitting and filename expansion.

Command substitution in fish returns a list of lines by default. You can print the result by re-injecting the newlines:

$ printf "%s\n" (cat file.txt)
lorem
ipsum

Or, you can set the IFS variable to an empty string so the line-splitting does not occur:

$ echo (cat file.txt)
lorem ipsum
$ begin; set -l IFS ""; echo (cat file.txt); end
lorem
ipsum

or

$ set contents (cat file.txt); echo $contents; echo (count $contents)
lorem ipsum
2
$ begin; set -l IFS ""; set contents (cat file.txt); end
$ echo $contents; echo (count $contents)
lorem
ipsum
1

I'm resetting IFS locally in a new scope to avoid destroying the current value in my shell.

Ref: https://fishshell.com/docs/current/index.html#expand-command-substitution