Skip to content

Commit

Permalink
Docs for "$(cmd)" and $(cmd)
Browse files Browse the repository at this point in the history
  • Loading branch information
krobelus committed Jul 13, 2021
1 parent 9767937 commit bf5d2d1
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Deprecations and removed features

Scripting improvements
----------------------
- fish's command substitution syntax has been extended: ``$(cmd)`` now has the same meaning as ``(cmd)`` but it can be used inside double quotes, to prevent line splitting of the results. (:issue:`159`).
- ``string collect`` supports a new ``--allow-empty`` option, which will output one empty argument in a command substitution that has no output (:issue:`8054`). This allows commands like ``test -n (echo -n | string collect --allow-empty)`` to work more reliably.

Interactive improvements
Expand Down
9 changes: 8 additions & 1 deletion doc_src/cmds/string-collect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ Description
``string collect`` collects its input into a single output argument, without splitting the output when used in a command substitution. This is useful when trying to collect multiline output from another command into a variable. Exit status: 0 if any output argument is non-empty, or 1 otherwise.

A command like ``echo (cmd | string collect)`` is mostly equivalent to a quoted command substitution (``echo "$(cmd)"``). The main difference is that the former evaluates to zero or one elements whereas the quoted command substitution always evaluates to one element due to string interpolation.

If invoked with multiple arguments instead of input, ``string collect`` preserves each argument separately, where the number of output arguments is equal to the number of arguments given to ``string collect``.

Any trailing newlines on the input are trimmed, just as with ``"$(cmd)"`` substitution in sh. ``--no-trim-newlines`` can be used to disable this behavior, which may be useful when running a command such as ``set contents (cat filename | string collect -N)``.
Any trailing newlines on the input are trimmed, just as with ``"$(cmd)"`` substitution. Use ``--no-trim-newlines`` to disable this behavior, which may be useful when running a command such as ``set contents (cat filename | string collect -N)``.

With ``--allow-empty``, ``string collect`` always prints one (empty) argument. This can be used to prevent an argument from disappearing.

Expand All @@ -34,6 +36,11 @@ Examples
::

>_ echo "zero $(echo one\ntwo\nthree) four"
zero one
two
three four

>_ echo \"(echo one\ntwo\nthree | string collect)\"
"one
two
Expand Down
4 changes: 3 additions & 1 deletion doc_src/language.rst
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,8 @@ The output of a command (or an entire :ref:`pipeline <pipes>`) can be used as th

When you write a command in parenthesis like ``outercommand (innercommand)``, the ``innercommand`` will be executed first. Its output will be taken and each line given as a separate argument to ``outercommand``, which will then be executed. [#]_

A command substitution can have a dollar sign before the opening parenthesis like ``outercommand $(innercommand)``. This variant is also allowed inside double quotes. When using double quotes, the command output is not split up by lines.

If the output is piped to :ref:`string split or string split0 <cmd-string-split>` as the last step, those splits are used as they appear instead of splitting lines.

The exit status of the last run command substitution is available in the :ref:`status <variables-status>` variable if the substitution happens in the context of a :ref:`set <cmd-set>` command (so ``if set -l (something)`` checks if ``something`` returned true).
Expand All @@ -588,7 +590,7 @@ Examples::

# Set the ``data`` variable to the contents of 'data.txt'
# without splitting it into a list.
begin; set -l IFS; set data (cat data.txt); end
set data "$(cat data.txt)"

# Set ``$data`` to the contents of data, splitting on NUL-bytes.
set data (cat data | string split0)
Expand Down
4 changes: 2 additions & 2 deletions doc_src/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,11 @@ Unlike other shells, fish does not split command substitutions on any whitespace
-lgobject-2.0
-lglib-2.0

If you need a command substitutions output as one argument, without any splits, use ``string collect``::
If you need a command substitutions output as one argument, without any splits, use quoted command substitution::

> echo "first line
second line" > myfile
> set myfile (cat myfile | string collect)
> set myfile "$(cat myfile)"
> printf '|%s|' $myfile
|first line
second line|
Expand Down

0 comments on commit bf5d2d1

Please sign in to comment.