Before writing this, I wondered the same what goes on inside a shell lifecycle. It was explained to me in one of my system administration class but we certainly do not recollect everything in a graduate course.
At work, I barely think before randomly typing a command, as to what is going on underneath the shell.
When we talk about the shell, we term it as a program that plays an important role in the system. Bash, and I would assume most other common shells, are implemented in C. It is the way a user talks to the kernel, by typing commands into the command line.
This is how it all goes down:
1] The shell has a prompt, where we (user) inserts/enters a command.
The shell reads the input, from the getline function’s STDIN (Standard Input), parses the input and its arguments (if supplied any). The shell also checks if the input entered is an alias of a sort, and if yes, expands the relevant value. Take for example “top -o cpu” is entered in the shell.
2] The shell looks for a program file called top where all the executable files are in the system (usually the $PATH variable)
Note on PATH variable: The $PATH variable is a list of directories the shell searches every time a command is entered. $PATH, one of the environment variables, is parsed using the ‘=’ as a delimiter. Once the $PATH is identified, all the directories in $PATH are tokenized which are then parsed further using ‘:’ as a delimiter.
3] Then, three system calls are made by order: fork / execve / wait
3a] The system call “Fork()” creates a duplicate copy of the calling process as its child. This is how virtually all processes on the system except for the first one (init) begin: as copies of the process which started them.
3b] The system call execve() is made which does three more things:
— Loads the new process a.k.a “top“
— execve() replaces the defining parts of the current process’s memory stack with the new stuff loaded from the top executable file.
— This is why fork() is necessary first in the creation of a new process — otherwise, the calling process ceases to be what it was and becomes something else instead; no new process would actually be created.
3c] The parent process continues to do other things, keeping track of its children as well, using the system call wait().