0

Foreword: I've already seen possibly related question Difference between 'ls' and 'echo $(ls)'

Does bash perform word splitting on output capturing? This guide -- mywiki.wooledge.org/WordSplitting says "no":

Word splitting is not performed on expansions in assignments. Thus, one does not need to quote anything in a command like these: [...] bar=$(a command)

But when I do res=$(find); echo $res output differs from just find:

$ find
.
./file2
./file1
./test.sh
$ res="$(find)"; echo $res
. ./file2 ./file1 ./test.sh
$ res=$(find); echo $res
. ./file2 ./file1 ./test.sh

aryndin
  • 239
  • Cannot reproduce with GNU bash, version 5.0.18(1)-release (x86_64-slackware-linux-gnu) – Arkadiusz Drabczyk Sep 27 '20 at 20:23
  • The the text that you quote does not apply to the output that you see, which is produced by echo. You may want to try echo "$res". – Kusalananda Sep 27 '20 at 20:34
  • @thanasisp sorry, I found out that firstly I used zsh as a shell :-D – aryndin Sep 27 '20 at 20:35
  • In that case, could you please clarify you question with that information, and possibly rephrase it? – Kusalananda Sep 27 '20 at 20:35
  • @Kusalananda ok, I will try to rephrase question – aryndin Sep 27 '20 at 20:36
  • 1
    When bash processes an unquoted variable reference (e.g. echo $res), it'll word-split the result (assuming default options). zsh does not do this (again assuming default options). – Gordon Davisson Sep 27 '20 at 20:37
  • @GordonDavisson does bash perform word splitting on output capturing? This guide -- http://mywiki.wooledge.org/WordSplitting says "no", but when I do res=$(find); echo $res it differs from just find – aryndin Sep 27 '20 at 20:41
  • @Kusalananda I've updated the question – aryndin Sep 27 '20 at 20:50
  • 1
    @The splitting doesn't happen in res=$(find), but it does in echo $res. See this question and its answer. Personally, I think it's easier to just double-quote all variable and command substitutions, rather than trying to keep track of where it's safe to omit the quotes and where it can cause trouble. – Gordon Davisson Sep 27 '20 at 22:48

1 Answers1

4

Note that the text that you quote only relates to the assignment to your variable res. There is no issue with that part.

The find utility produces newline-delimited pathnames as output, as you show.

Assigning this output to a variable will retain the newlines (except for the last, which is removed).

It's all good so far, but then...

When you call echo with your unquoted variable in bash, the variable's value is split on spaces, tabs and newlines (by default), and the resulting strings undergo filename generation (globbing). The resulting words are then given as individual arguments to echo.

The echo utility will output its arguments delimited by space characters (and add a newline at the end). This is what you show happens with echo $res.

To see the value of the variable without letting the shell split it into multiple words and do filename globbing on them, double quote the variable's expansion: echo "$res", or even better, printf '%s\n' "$res" (see Why is printf better than echo?).

In short, the expansion of the variable in the call to echo must be quoted.

Kusalananda
  • 333,661