What happens when you type ls -l *.c in the shell

Geraldine Meneses
6 min readAug 19, 2021

--

Let’s start by wondering …

What is Shell?

In computing, the shell or command interpreter is the computer program that provides a user interface to access the services of the operating system.

Now in Linux the Shell is in charge of establishing communication between the kernel and the user of the Linux System, that is, it is an interface with our Operating System. Then thanks to him we will be able to give the necessary orders so that our computer system performs the tasks we need.

shell and kernel process diagram, starting with the user’s request and showing the process path that that command does to return a result
Shell and Kernel process diagram

What are shell commands?

Before learning about some of the commands available in the Shell, you must be very clear about the tasks to be carried out, that is, you must differentiate between administration tasks and regular use of the system.

Commands are invoked by name and options or parameters are passed to them by means of the minus sign “-” followed by one or more letters. For example ls -la.

ls -l *.c

ls: It shows the names of the files and subdirectories contained in the directory you are in. Only the names of the files are obtained, without any other information.
ls -l: This is the long list option. It shows all the information of each file including. Protections, size and date of creation or of the last change introduced.
*: Represents any set or sequence of characters.

If we only write ls in the terminal, we will end up listing all the files (not hidden) that are in the current directory:

root@c698ec171c6e:/home/simple_shell# ls
AUTHORS e e_p.c m main.c match.c p shell simpleshell.h v
brokentoken.c env.c execute_path.c main man_1_simple_shell o README.md shell.c
root@c698ec171c6e:/home/simple_shell#

We can see that we have files of all kinds, but what if I add another parameter? now I want to add the command -l according to the previous table, this added command should list the files with the detailed information, then the result would be something like this:

root@c698ec171c6e:/home/simple_shell# ls -l
total 3052
-rw-r--r-- 1 root root 510 Aug 17 19:39 brokentoken.c
-rwxr-xr-x 1 root root 16936 Aug 18 17:42 e
-rw-r--r-- 1 root root 184 Aug 17 19:51 env.c
-rw-r--r-- 1 root root 552 Aug 17 20:31 e_p.c
-rw-r--r-- 1 root root 559 Aug 18 12:28 execute_path.c
-rwxr-xr-x 1 root root 17400 Aug 17 19:13 m
-rwxr-xr-x 1 root root 17560 Aug 18 11:58 main
-rw-r--r-- 1 root root 1467 Aug 18 12:50 main.c
-rw-r--r-- 1 root root 728 Aug 14 18:50 match.c
-rwxr-xr-x 1 root root 16840 Aug 16 15:34 o
-rw-r--r-- 1 root root 2952592 Aug 17 20:32 p
-rw-r--r-- 1 root root 2016 Aug 13 16:32 README.md
-rwxr-xr-x 1 root root 17264 Aug 17 13:37 shell
-rw-r--r-- 1 root root 1526 Aug 17 16:45 shell.c
-rw-r--r-- 1 root root 615 Aug 18 11:37 simpleshell.h
-rwxr-xr-x 1 root root 16696 Aug 17 19:51 v
root@c698ec171c6e:/home/simple_shell#

Good! We have a list with all the information of each file, if we read from right to left we can say that this command helps us to see detailed information of the files. In the following image, each part is named:

Description of the detail of a file

Now, the ls command admits the substitution characters or meta characters such as the symbol *, now when we join these commands and include an extension in this case the .c it would be:

root@c698ec171c6e:/home/simple_shell# ls -l *.c

And the result of this would be the long list of all files that end with the extension .c:

root@c698ec171c6e:/home/simple_shell# ls -l *.c
-rw-r--r-- 1 root root 510 Aug 17 19:39 brokentoken.c
-rw-r--r-- 1 root root 184 Aug 17 19:51 env.c
-rw-r--r-- 1 root root 552 Aug 17 20:31 e_p.c
-rw-r--r-- 1 root root 559 Aug 18 12:28 execute_path.c
-rw-r--r-- 1 root root 1467 Aug 18 12:50 main.c
-rw-r--r-- 1 root root 728 Aug 14 18:50 match.c
-rw-r--r-- 1 root root 1526 Aug 17 16:45 shell.c
root@c698ec171c6e:/home/simple_shell#

We can notice that it does not take into account the other files that were listed in the first command when it was only ls -l and that it only showed all the files that contained a .c extension.

This would be all the Command would do, but it doesn’t end here…

How does the Shell work from another perspective?

When we write a command in the terminal in this case ls -l it happens to be stored in a getline this function reads an entire line of stream, storing the text (including the new line character and the termination character) in a buffer its prototype is: ssize_t getline (char ** lineptr, size_t * n, FILE * stream);.

Once the command is written and stored in the getline we pass it through thestrtok function. This function helps us to separate the string by the assigned delimiter, in our case assigning the space as the delimiter, so that each command is stored in separate memory spaces and arguments can be evaluated. The prototype of strtok is: strtok (string, delimiter);

Gif about getline and strtok functions

once the strings have been divided, we proceed to evaluate the first element of memory in the paths of the environment variables PATH with the functions execve and fork.

exeve is a function that executes the program indicated by filename and must be an executable binary. In the second case, the interpreter must be a valid path name for an executable that is not itself a script and that will be executed with the arguments [arg] (optional) plus the file filename to interpret, its prototype is: int execve (const char * filename, const char * argv [], const char * envp []);

fork is used to start a new process within the main process, this second process is known as the child and the main process is known as the parent. At this point the fork works once the parent process is executed, it creates a second execution (child) where that child process executes an internal function while the parent waits with the wait command for the child process to finish to continue its function, there are scenarios where the child process does not function and returns 3 possible results:

  • -1 = Creation of child process was unsuccessful.
  • 0 = Child process is executed
  • 1 = Parent process is executed
Flowchart explaining the fork () process

Once the command path is obtained by going through the environment through the PATH, it executes its file returning the command function in this case ls and evaluating if it has more arguments marked with the symbol “-”, the executable file will return what the command calls in our case the long list -l.

Touring PATH

This is what the Shell executes internally when you give it a command! We invite you to take The Complete List of Shell Commands and try to combine the commands, so that you can get to know and learn this language more easily!

This blog is designed and written by:
Diana Carhuamanta and Geraldine Meneses

--

--

No responses yet