This is not the first version of this question, i asked before and i feel enough enhancement to rewrite it from a different angle and after a beautiful experience working on our own shell in Holberton School project.
Typing commands in the shell is just a simple keystroke on our keyboard and a blink time of waiting and “Voila” we see the result. but the real hard work is under the hood and to walk through this process i step an example of “ls -l” command which expect to show me the list of the present file in the current directory:
Read the line — Keyboard stroke
The first step of course is about reading what the user type, here when the shell program ask a help from the system call function to translate the standard input , sent by the keyboard, into a string of character. and then save it to further use, until the hit of the return ‘new-line stroke’ when the shell can understand the end of the command.
In this second step the computer tries to understand what the user wrote, and the other side of the human/machine conversation starts to figure out what language the user speak, and like a child, it try to decompose the line (the user speak) into understandable tokens and a chunk of commands. Based to this tokens the shell program dispatch your demand to the responsible service which mean if the shell need an external program to handle your command, a builtin function or may be it decide to drop out (gently) your request.
The decision make of the lexical analyzer is based on the available options and resources, the most valuable resource is the ‘environment’ variables especially the “PATH”, which is the main indicator if this command is one of the available program or not. the PATH variable is a list of paths to the possible locations of installed programs in the system. when the shell found the program in this path, consider it as an external program. else is facing two options: either a builtin function or not found based on a predefined list of the built-ins.
In our example “ls -l” the lexical analyzer split the command on two arguments the first is probably the name of the program the second is the passed argument. so after a simple search in the PATH the shell find the suitable location of the “ls” program which is the “/bin” folder. then it’s time to pass all this information to the execution phase.
Execution of the command
The execution phase is quite tricky according to the limitation of the system, in other words the shell will call another program the “ls” one in our example to participate on the service of the user. but to execute the “ls” we need to frees the “scenes” and terminate the shell itself and give way to the execution of the external program which is quite danger. So to understand the “scene” approach we come at the process ‘is the instance of a computer program that is being executed by one or many threads’. each executed program in the system have an identifier at the runtime called “pid” is a special unique id for the program and his child knowing each program can have child helps for the execution of the service. The shell here is the parent process asking for an external program to achieve the request of the user so it need to fork a child process under his parental authority for the execution of the “ls” program.
So to summarize the walk, we found that the “ls -l” command passing the read phase, then analyzed into understandable tokens by the machine, the the execution phase. with this simple command we skip many phases available in the shell like the expansion and the symbolic feature. May be in the next article :).