What happens when you type ls -l in the shell

Geoffrey Zoref
4 min readNov 26, 2019

--

When a user types ls in a command line, the files of the current directory are displayed. ls is short for ‘list’. The -l is an option of the ls command, one of several, which stands for means ‘long’, or ‘long format.

When a user enter ls int a terminal, they will get back a list of files like this

The result of typing ls command

When ls is accompanied by the -l command, the result looks like this

ls -l prints the directories files along with data about the files

That’s what the output is when you type in this ls -l command, but what is really going on behind the scenes, on the lowest level of your systems? To answer that we need to understand what is happening in the shell.

What is a Shell?

The shell is a program that takes commands from the keyboard and passes them to the operating system to interpret and execute. The shell is a text-only interface that is run via the system’s terminal.

Today the shell has mostly been surpassed by the Graphical User Interfaces (GUI) such as Windows and Os/x. Despite this, the shell is still a powerful environment for users who take advantage of its difficult learning curve, and is often a more efficient and flexible way to use your computer.

How does it work?
When you enter a shell, you will be greeted by a command prompt, which can vary from shell to shell, but is often a ‘$’ or a ‘>’’. The prompt is running in a loop; in our case we chose to use a do while loop to display our prompt.

A function that reads user input is called when the user types in a command called by the getline() function. The user input then gets passed to a command which filters the two types of arguments in a shell: executable system calls like ls and pwd and builtin functions.

Builtin functions are those that are called from the source code of the shell as opposed to external executable commands, which are called are called from the file system and originate in the system’s kernel.

Where is ls called from?

Before the command is filtered between builtin and executable, and ls -l is found to be an executable, and after the user input is read, it is parsed by a function we wrote. Then we call a function to tokenize the user’s argument into an array using strtok() . The string tokenizer accepts two parameters, a string and a deliminator, and returns the string that it’s passed as a pointer to a NULL terminated string. This step is crucial for the shell to work, as will be explained in the next part.

Where is the ls executable?

The PATH is a string of directories which contain the executable functions.ls and all the other commands are found within the directories of $PATH.

Output of the $PATH variable

When looking for the directory that contains the executable for ls, we concatenate a / to each PATH directory, appending ls to each directory in order to find bin/ls, which contains the functionality of the ls command.

When the correct bin directory is found, our function will call the fork system call, which is essentially the start of our shells execution. fork allows the program to create child and parent processes, each with a unique process identification number, or pid. By following the pid process, we have an integer to follow and compare in our conditional statements, allowing us to call execve at the appropriate time.

When the correct process is running ,the execve system function is called to actually execute the bin/ls executable, thus listing the directory files in long for order.

--

--