Issue
In the following example I can't figure out why the second echo
replaces blank characters by new lines
$ ls ..
info helps TODO
$ var=$(ls ..)
$ echo $var
info helps TODO
$ echo "$var"
info
helps
TODO
Is it because ls ..
does not really output blanks and the use of quotes allows to save these characters?
Solution
ls
’s documentation says:
The default format shall be to list one entry per line to standard output; the exceptions are to terminals […]. If the output is to a terminal, the format is implementation-defined.
I.e. it’s implementation-defined what ls
writing to a terminal prints, but quite commonly implemented as columns. The implementation in this case probably being bash.
So ls
prints columns.
var=$(ls)
prints one file per line and stores that in $var
.
echo $var
has the shell split* $var
into arguments, since it’s not quoted (naughty!) and echo
receives multiple arguments which it then joins with spaces†. This happens to look a lot like ls
printing columns, but notice the slight difference in spacing in the question!
echo "$var"
on the other hand hands $var
verbatim, newlines and all, to echo
in a single arguments, which echo
then prints.
* Assuming $IFS
isn’t set to something crazy, fields are split at newlines.
† See echo
’s documentation: ‘The echo utility arguments shall be separated by single <space> characters’
I know the question is tagged bash and that I link to POSIX documentation. 🤷
Answered By - Biffen Answer Checked By - Pedro (WPSolving Volunteer)