diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a22ffa98c1b9..6716efd1dc8d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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 diff --git a/doc_src/cmds/string-collect.rst b/doc_src/cmds/string-collect.rst index e3e0b5f3199d..19e7579722bd 100644 --- a/doc_src/cmds/string-collect.rst +++ b/doc_src/cmds/string-collect.rst @@ -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. @@ -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 diff --git a/doc_src/language.rst b/doc_src/language.rst index 95b483ecc1d9..e754684eb8e1 100644 --- a/doc_src/language.rst +++ b/doc_src/language.rst @@ -569,6 +569,8 @@ The output of a command (or an entire :ref:`pipeline `) 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 ` 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 ` variable if the substitution happens in the context of a :ref:`set ` command (so ``if set -l (something)`` checks if ``something`` returned true). @@ -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) diff --git a/doc_src/tutorial.rst b/doc_src/tutorial.rst index b63a59db364a..9ec75290ea17 100644 --- a/doc_src/tutorial.rst +++ b/doc_src/tutorial.rst @@ -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|