Monday, October 10, 2022

[SOLVED] echo "$var" and echo $var not producing the same output

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 .

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 and that I link to POSIX documentation. 🤷



Answered By - Biffen
Answer Checked By - Pedro (WPSolving Volunteer)