-3

I have 2 files in my folder as shown below

$ ls -l
total 1
-rw-r--r-- 1 user user-group 0 May 10 14:49 test
-rw-r--r-- 1 user user-group 0 May 10 14:49 test1

Listing the files is showing normal. But why does below command shows both the lines merged in a single line in bash?

$ echo `ls -l`
total 1 -rw-r--r-- 1 user user-group 0 May 10 14:49 test -rw-r--r-- 1 user user-group 0 May 10 14:49 test1
mklement0
  • 382,024
  • 64
  • 607
  • 775
Deepak Janyavula
  • 348
  • 4
  • 17

2 Answers2

6

To complement Colwin's effective answer with why the double quotes are needed:

If you pass an unquoted command substitution (e.g, `ls -l` or, better, $(ls -l)) or variable reference (e.g., $var), the shell modifies the command output / variable value before passing the argument to the command.
This applies to all POSIX-compatible shells, not just bash.

Specifically, the following so-called shell expansions are performed:

  • word-splitting: the output is split into (potentially) multiple words by whitespace, including newlines (by default; the split characters can be set via $IFS)

  • globbing (filename expansion): each resulting word is interpreted as a filename pattern and matched agains files in the current directory, and each matching filename becomes its own word, with all resulting words replacing the original word; by default, if nothing matches, the word is left as-is.

The resulting words are then passed as individual arguments to the target command.

By contrast, if you double-quote a command substitution ("$(ls -l)" or variable reference ("$var"), these expansions do NOT take place, and the output / value is passed as-is to the target command.


Therefore, in the case at hand:

  • the shell removes all newlines from the output of ls -l
  • and then passes the resulting words individually, as multiple arguments to echo

echo simply concatenates multiple arguments you pass to it with spaces, which is why you're seeing the single-line output printed in your question.

In short: Due to not double-quoting `ls -l`, echo `ls -l` prints a space-separated, single-line list of the words contained in the output from ls -l.

mklement0
  • 382,024
  • 64
  • 607
  • 775
5

Since you are using command substitution here and echo, inorder to get echo to show your output on multiple lines you will need to quote the output.

$ echo "`ls -l`"
Colwin
  • 2,655
  • 3
  • 25
  • 25
  • 1
    Nicely done; worth adding that [modern command-substitution syntax `$(...)` is preferable to legacy syntax `\`...\``](http://mywiki.wooledge.org/BashFAQ/082). – mklement0 May 10 '17 at 14:59