Tracking down the step by step of the “ls” command in the Shell

The Shell prompt from the user intructuctions (commands) to communicate to the core of  system
The Shell prompt from the user intructions (commands) to communicate to the system kernel

The Shell is a user’s program that communicates with the system kernel through commands prompt from the user and then later interpreted in a way that system can understand it, so the commands that the user type in the Shell translates into instructions and system calls.

Systems calls are a native function of the kernel which one can manipulate important information and hardware of the computer as is shown in the following flow chart:

System call vs Library function flow chart

Now let’s see how the system kernel interprets the command “ls -l” that displays the lists of files in the path where the user is located together with the additional information such the permissions of files as shown in the following:

Normally once the Shell is prompt to the user a dollar $sign is blinking on window meaning the shell is waiting for an input from the user as shown below:

Dollar $ sign prompt in the shell

Once the user types a command in the Shell, the system read it with the getline() function that takes the command as a string and then save it into the buffer, getline() function shown below:

getline(&line, &bufsize, stdin)

Later, the function strtok() will take the string inside the buffer and it will split it into an array of characters, so from the command ls -l will later transform it in to ["ls", "-l"]. The main idea of transforming that way is for the system to understand clearly.

The shell will check the first argument of the tokenized string in the global variables folder with the envcommand and it will compare it with the list of commands in the PATH/bin/usr. Once it finds it proceeds to read the other tokens that could be part of the command, in this case, the flag -l, the Shell will recognize a flag if as it has a - at the beginning of the tokenized string.

/usr/local/sbin/ls -l => This where the command is located when it conacatenates with the tokenized string

With the route mentioned before the Shell can execute it with the following function:

execve(PATHroute, token, NULL)

The most important thing that happens when the command is executed it is the execution of the functions execve() ,fork()and wait(), fork creates a child process (PID) whereexecve() execute the file in the path /bin/ls -lwhile the parent waits for the response of the child process, as shown in the next flow chart:

PID Flow chart

The execve()function has three parameters, -PATHroute contains the route and the command to execute, the second one contains the arguments that user prompt to the shell ls -l and the third one ends it, as shown in the flow chart below:

execv() Flow Chart

After all those steps the command ls -l is executed, then frees the memory used for the process, and for the last step, it exits it and finally the Shell prompt with the $ again waiting for the next command.

For a better understanding of how the Shell works in more detail please have a look at the following flow chart.

Shell Flow Chart

If you have any questions, comments or suggestions, feel free to contact me on Twitter @codesectest


Contributors: Twitter: gustavo55432603 and Medium: @gustavotovarcabrera