I have a folder containing two files scrap.sh and data.txt. In the bash script I have the following script

x="$(ls -l)"
echo $x

The output of running this script is all on one line

total 4 -rw-rw-r-- 1 gary gary 0 Feb 9 21:52 data.txt -rw-rw-r-- 1 gary gary 21 Feb 9 22:00 scrap.sh

However, when I change the script to the one-liner

echo "$(ls -l)"

I get this

total 4
-rw-rw-r-- 1 gary gary  0 Feb  9 21:52 data.txt
-rw-rw-r-- 1 gary gary 16 Feb  9 22:01 scrap.sh

Why is there a difference in the output?! The first one produces everything on one line and the next one on two separate lines. Both scripts seem to be functionally the same.

  • Expanding variables without putting double-quotes around them (e.g. echo $x instead of echo "$x") causes its value to be split into "words" and any of those that contain wildcards to be expanded to a list of matching filenames. You almost never want this, therefore you should (almost always) double-quote your variable references. Oh, and run your scripts through shellcheck.net -- it's good at spotting common mistakes like this. – Gordon Davisson Feb 10 at 5:34
x="$(ls -l)"
echo $x

By not quoting $x you make the shell perform word splitting on the expanded value. The result is each chunk like data.txt or -rw-rw-r-- is sent to echo as a separate argument. Newlines and multiple consecutive spaces no longer "separate" substrings, they separate arguments in the shell and don't get to echo. The tool gets multiple arguments and prints them, separating with single spaces.

Word splitting is not the only thing that happens, there's also filename generation. In your particular case the latter has no impact though. Please read these answers to learn about the general case.

Note if you run echo $(ls -l) (i.e. without quotes), the result would be like the one from echo $x. You did not only change the snippet to a one-liner; you added the missing quotes. Hence the difference.

echo "$(ls -l)" itself is wrong for another reason. See this question of mine. I understand (I hope) you used it only in comparison to the original two-line code. The two-line code (after adding quotes) may be justified if it's not the only code. This statement is elaborated in the answer to the already linked question.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.