Picture of JS Simple Shell

What happens when you type “ls -l” in shell?

Jian Huang
3 min readAug 28, 2018

I hope you learned a lot when we last talked about the technicalities after typing “ls *c” into the terminal. In this blog, we will explore deeper into the shell by using a similar example: “ls -l”.

Here we go.

When you type “ls -l” into a shell and press enter, the shell parses your input as a string and tokenizes the string based on delimiters like spaces, semicolons, and logical operators. Using these “tokens” the shell is able to process multiple commands, but for our case, we will only be dealing with one. The input “ls -l” will be broken into two strings “ls” and its argument “-l”. The command “ls” is then checked with a list of known aliases. If it were found, then the value stored in the alias “ls” will be used as the command. If no alias were found, then it will move onto the next checks.

Next, “ls” will be checked against a list of builtin commands. Again, if “ls” were a builtin, then that builtin will be run. If it wasn’t found, then the shell moves onto checking the directories in the PATH environment variable. The executable for “ls” will be checked in each directory listed. This is the final check to see if “ls” is a valid executable. If found, the shell will move onto executing the command. Upon failure, an error will be thrown and an error message will be displayed for the user.

Shell checks all directories in PATH to find executable ‘ls’
Shell finds an executable called ‘ls’ in /bin directory

The shell knows that “ls” is in the “/bin” directory, so shell will use that executable. It first uses the “fork” command to create a child process: an identical replicate of its parent process with a different PID. In this child process, shell executes the command by passing in the command, the array of tokens, and then a list of environment variables to one of the “exec” commands. Creating a child process is imperative because the exec command overwrites the stack of the calling process, replacing it with its own. Therefore, for shell to run indefinitely, a child process has to be created and parent will wait for the child to finish its execution before it continues.

After the arguments are passed into “exec” command in the child process, “ls -l” will display a list of all directories and files in long format for the user. Afterwards, the shell will display a new prompt string (PS1) to the terminal, allowing the user to input more commands.

That’s all folks.

Authors:
Jian Huang
Stephen Chu

--

--