What happens when you type ls *.c?

Santiago Zapata Bedoya
4 min readNov 16, 2020
image source: https://www.geeksforgeeks.org/practical-applications-ls-command-linux/

Alright.. Before you pass this point, make sure that you understand the following definitions:

  • Shell
  • Unix-like commands
  • Wildcards
  • Shell variables
  • Alias

If you don’t know them, don’t worry, I’ll try to explain them as easy as possible just for you to be able to understand. So let’s start!

What does the ‘ls’ command do?

Simple.. It prints all the files and directories that are contained in a directory. Let’s take a look of it:

image source: https://www.howtogeek.com/107808/how-to-manage-files-from-the-linux-terminal-11-commands-you-need-to-know/

So now we can see that after we press ‘Return’, the terminal prints some names on the screen. Well Those names are either files or directories. They can be differenciated by their name color.

Now what happens when we write a ‘*.c’?

That ‘*’ right there is called a wildcard, and it is a trick that we can use. It matches any characters in a filename. Knowing this, then the prompt will translate this command as: “List all the files that end with a ‘.c’”. Example please! Here it is:

Source: My own terminal

As you can see. It listed all the files with a ‘.c’ termination.

And what happens in the background?

First: Tokenization.

The shell takes these two words: ‘ls’ and ‘*.c’ as they are separated by a space, and the shell reads the spaces, tabs and newlines as separators if they are not between quotes. For example:

Image source: http://linuxcommand.org/lc3_lts0080.php

We can see that no matter how many spaces we put, the shell will put only one space. But if you put it between quotes ‘“”’ it will interprete it as plain text.

Image source: http://linuxcommand.org/lc3_lts0080.php

Now let’s get back to our question: What happens when we type ‘ls *.c’ and hit enter?

So first the shell reads that the first word, in this case ‘ls’ is an existing command, it also searches if that is an alias of any other command. An alias as its name tells us, is something used to refer to a certain command. For example if I want to call ‘ls’ as ‘Martin’ I can do it and the shell will know that it is an alias for the ‘ls’ command. After it proves that that word is either an alias for an existing command or the command itself, then it goes to the next step. Otherwise it will return an error message.

It evaluates the next word ‘*.c’. Now the shell bumps to the ‘*’ wildcard and it will make first an expansion before continuing with the command. But wait.. What?
So we have something called expansion. There are different types of expansions: aritmethic, tilde, brace, pathname, etc. Here we are bumping to a pathname expansion and this means that the shell will expand this ‘*’ into the name of the files that end with ‘.c’ inside the working directory.

We can see an example with the echo command. The echo command displays whatever you write in front of it as you saw in the example above. But when we use the ‘*’ wildcard something interesting happens. Let’s take a look:

Image source: http://linuxcommand.org/lc3_lts0080.php

If the bash interpreted first the command and then the wildcard, then it would just print the * on the screen.

After the expansion is finished, the shell will continue to perform the command. The shell starts to search for the command in the built-in functions and if it’s not there, it will find the $PATH. This is an environmental variable that specifies where are the executable programs located.

Here’s an example of what I’m trying to say:

Source: My own terminal

And finally.. After this whole process is done, the terminal prints the command line prompt again, this is also known as PS1, which is a global variable that keeps the hostname, username and the full name of the path of the user directory. The last character of this variable can be either # or a $. This tells us if we are working as normal users ($) or as root users (#).

--

--