If you input the command ls * and echo *, you will notice the remarkable discrepancy between the results. The former recursively includes while the latter totally excludes files in subdirectories. Don't they behave the same for pathname expansion?


ls by default lists the contents of directories if passed as arguments. When you pass * to your shell, your shell expands * to all files and directories (in the present working directory) and then ls takes these arguments and processes them. As a result it lists the contents of those directories specified along with the files in the present working directory.

In the case of echo, the shell expanded the * and you do not get the directory contents, because echo just prints what was passed to it as arguments.

You can tell ls not to show the contents of directories by using ls -d *.

Given this setup:

$ mkdir dir{1,2}
$ touch file{1..3} dir{1,2}/morefiles{1..5}
$ ls
dir1  dir2  file1  file2  file3

Passing * to the shell (bash), causes bash to expand * to dir1 dir2 file1 file2 file3. Using echo with *, will cause echo to display what the shell expanded from *:

$ echo *
dir1 dir2 file1 file2 file3

However given arguments of directories ls will, by default, expand the contents of the listed directories:

$ ls *
file1  file2  file3

morefiles1  morefiles2  morefiles3  morefiles4  morefiles5

morefiles1  morefiles2  morefiles3  morefiles4  morefiles5

You can either drop the * on ls (as illustrated after I created the example directory structure), or as mentioned in my answer use ls -d * instead:

$ ls -d *
dir1  dir2  file1  file2  file3

This stops ls from showing the contents of dir1/ and dir2/.

  • But why ls * command does not return the sudirectories as a list right in pwd? (Only return files in pwd as the first list, and executes ls to each subdirectories in pwd as 2nd, 3rd, and more lists.) – user43312 Sep 8 '13 at 15:05
  • But why ls * command does not return the sudirectories right in pwd in the 1st list? I could see that the result is composed with several lists, each of which could be seen as an execution of an ls command. Only files in pwd are returned in the first list, and ls is executed to each subdirectories in pwd as 2nd, 3rd, and more lists. – user43312 Sep 8 '13 at 15:16
  • That's just how ls displays it's output, it is from one ls command, not several, you can see this if you do ls dir*, which will only show the contents of the two directories. – Drav Sloan Sep 8 '13 at 15:22
  • @slm Blatent theft of the mkdir/touch use from an earlier answer you gave. It definitely is a succinct way to provide an example :) – Drav Sloan Sep 8 '13 at 20:03

Just to clarify DravSloan's excellent answer, there is no discrepancy. * is expanded in both cases by the shell and in both cases it expands to exactly the same thing. The difference is in the way echo and ls treat their arguments.

echo will just print each of the arguments you give it. ls will list directory contents as the manual says. So, in both cases, the shell executes the program on the left (echo or ls) and the program in question does whatever it is supposed to do with each of its arguments. The result is different because the programs are different, not because * is expanded differently.

  • Yeah may be that's where the OP's confusion arises - i've tried to clarify my answer a little! – Drav Sloan Sep 8 '13 at 15:40

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.