The story behind ls -l *.c

Miguel Pacheco
3 min readApr 12, 2021

--

Hello and welcome to another blog, in this case. We are going to talk about what happens when we type ‘ls -l *.c’

Probably for a lot of people, ‘ls’ is the first command that you learn when you start learning Linux.

Example of a ls command

As you can see ‘ls’ print all available files in the current path or directory. Normally, the list is sorted alphabetically. However, you can to sort it in the way you want

Well, now that we know that what ‘ls’ command does, now we need to know what makes that thing ( -l) well, “-l” is a flag (you can see more flags if you use the command “man ls” in your terminal) that indicates that we need to print all the files in long format

Example of ls -l command

In this case we can see that the ‘ls -l’ command lists all the files sorted alphabetically and we can see more information of the files for example, the permissions of the file, creation date, etc.

Now, the last piece of the puzzle. What is ‘*.c’ ? Well, in this case the ‘ls -l *.c’ means that we need to list in long format all the files that ended with “.c” in his name

Example of a ls -l *.c command

The last thing later than the shell returns the “result” is that the shell prints the prompt again and wait from another imput

Well… but, what really happens when we type ls -l *.c and press enter?

  1. After print the prompt and the ‘ls -l *.c’ is entered, the keyboard realizes that characters have been inserted and pushes them to the shell. The string is passed as one single string. Later that string is splited into tokens excluding the white spaces. Now, our command has now three tokens, ‘ls’, ‘-l’ and ‘*.c’, later this tokens are placed in an array of strings. This process is called Tokenization.
  2. Next, the computer checks if tokens are built-in functions or not. If the command is a built-in, the shell runs the command, without using another program. For example, ‘env’ is a built-in, but, ‘ls’ isn’t a built-in, so now system needs to find the executable or program for ‘ls’.
  3. After that, the bash interprets the command. The first search for the command ‘ls’ is done through $PATH. $PATH is an enviromental variable which holds all the paths of the executable programs. The search calls a series of functions. Each path in PATH variable is searched for the executable for the executable that corresponds to in this case ‘ls’. BASH invokes the function fork() to create a child process. After we need to put the command pid and ppid in order to search for the father process and the child process. If the pid returns 0, we find the child process and the after we make stat() to check if there is a matching executable. For the father process (ppid) we need to execute a wait system call.
  4. After all these, when the file is located at ‘/usr/bin/ls’, BASH performs the execve() command to run the file
  5. Finally, execute the command: the program is in memory and is ready to run when it gets a chance. However, how are directories and files read using ‘ls’? In order to do this, a list of functions are executed internally to access the final output. The ls utility uses a function to read the directory content, which invokes a system call to read the list of files in the directory by consulting the file system’s inode entries. As soon as all the entries have been retrieved, the system call returns. Finally, the shell prints the prompt. The prompt is stored as an enviroment variable called PS1. the list of files is returned to the prompt.

--

--

Miguel Pacheco
Miguel Pacheco

Written by Miguel Pacheco

Student at Holberton School | Aspiring to be a Front-End Web developer

No responses yet