What happens when you type ls -l in the shell
Daniela Morales
Software Engineer | Python & Golang Developer | Data Science Engineering Student
Before starting .. What is the shell?
The Shell is a command interpreter. It is simply an alternative way to control a computer based on a text interface. We can ask the computer to run a program or provide us with information using the mouse cycling in different places on the desktop or we can write an order to achieve the same goal.
Giving a visual example of where our shell is located internally it would look like this:
As we can see, there are several types of interpreters such as: bash, ksh, csh among others!
This will be our working environment from our shell :
Now that we know about the shell, let's dive into what happens when we type the command to list files in a certain directory in the shell!
As we already know the command "ls" with the flag "-l ", it will list all our files in long format and clearly with more information compared only when we use our command ls, as illustrated in the following image:
Now, if we go deeper when we write "ls -l" in the shell ... what happens in the background?
1-When contact is made on the keyboard membrane, the CPU receives an interrupt signal from the interrupt controller and the routine that handles the interrupt. When in this case we write our command "ls -l".
1- Explaining the previous image, when we start any process or also called a child we will always create our father, we do this using our fork() system call.
2- After having made our fork, our child process will be generated automatically, which in this case will be our "ls -l" program, after our fork(), if this is successful, we will check this:
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { int id; id = fork(); if (id == 0) { printf("%s %d\n", "I am the child my ID is:", getpid()); } else { printf("%s %d\n", "I am the father my ID is :", getppid()); } return 0; }
in the code snippet above we can check when our frok and child process are successful, a short explanation is that the value returned by fork allows.
Differentiate the parent process from the child, since fork returns 0 to the child and the child ID to the parent.
- Note : In case of error it returns the value of (-1).
3- Now the next step taking into account the explanatory diagram of how most of our "ls -l" process works, is when executing our child process with the exec() system call.
#include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> int main(void) { int pid; int status; char *args[3] = {"ls", "-l", NULL}; pid = fork(); switch(pid){ case -1: /* Failed creating the child */ perror("Error in fork"); exit(-1); case 0: /* child process created */ execvp(args[0], args); /* execvp() of our child */ perror("Error of exec")/* we check in case exec fails */ exit(-1); break; default:/*father*/ while(wait(&status) != pid); if (status == 0) printf("normal execution of the child"); else printf("Error of child"); } exit(0);/* exit successful*/ }
The parent process generates a child and waits for it to finish. The child process creates a new program image by calling the command "ls -l". The switch helps us to know where we are. Remember that the child in pid has 0 and the father the child's pid.
This is basically what happens when we write the command "ls -l" in our shell Now what happens when from our keyboard we give ENTER ?
When we enter from our keyboard what happens is that within our main environment variable called PATH the address of our program is searched for, in this case "ls" within PATH these addresses are divided by this character ":"
We can verify it using the printenv or env command, from our shell:
we can see the path in the part that is underlined in white, which is separated by each address by ":" here we find the address of our program "ls" which is: "/bin/ls" (which we can also verify with the command which or whereis unless it's a built-in), the final step is the successful execution of our command "ls -l" with its respective output and shows the result on screen.