Under the hood of a Linux shell using ls -l

Mar 29, 2018 · 2 min read

ls is a shell command that lists files and directories. Using the -l option, ls will list the files and directories in “long list format” which includes details about the files such as permissions, ownership, etc..

Steps that the shell goes through when processing a users input

Reading the users input from stdin:

After entering ls -l in the command line, the shell then reads the user input from stdin by using getline(&string, &bufsize, stdin) and stores it into a buffer.

Tokenizing the user input string into arguments:

After reading the user input line, the buffer holding the input string value is broken down into tokens (separating the input string into individual words) with a delimiter of a space “ ” between ls -l.

Checks for any alias and builtins:

The shell checks to see if “ls” is an alias and/or builtin. Here are some examples of builtin commands: cd, echo, exit, help, env

Checks the PATH:

After the shell checks for any alias and builtins of ls, the shell will try to find the command in the PATH environment variable.

In order to check the PATH, the shell creates a copy of the PATH to be tokenized and separate directories by a colon “ : ”.

Once the absolute path is found, in the file/usr/local/bin/ls , the shell is now ready to start the child process in order to execute the command.

Creating a process using fork():

After finding the absolute path to the file, the shell now needs to create the child process using the fork() system call. This is needed so that when after the command is executed the shell prints the prompt again and does not exit the shell.

Executing the command using execve():

Once the child process is created, the shell can now use the execve()system call to execute the command. The parent process then waits until the child process is executed using wait(). After the command is executed the child process will be terminated and the parent will stop in wait(), printing the command prompt again.