Under the Hood: Unix Remix

What happens when you type ls -l *.c in the Shell?

Recently, at Holberton School, we were assigned with a project where we create our own simple shell program with a partner in our cohort. The goal of it is to learn all about all the inner workings of a shell.

File System Tree:

This is where files are organized into a hierarchical directory structure, and each directory contains its own files. The system tree when displayed in the terminal is separated by a forward slash “/”. The first directory is the highest directory in that system tree. Each directory to the right, divided by each forward slash, indicates the next directory in the hierarchy on the level below the previous. When the user searches for content, files or directories, this shows the order or path that is taken when the system searches for the file or directory. It looks just like a tree!

What is a Shell?

It is, in all its essence, the command line interface (CLI). Its interface basically reads a command like cd (change directory) then passes it to the operating system to carry out.

Now you understand the inner workings of the file system on your computer, but without the Shell, a typical user would see a file system on their computer as icons of folders that have titles, and then once clicked, contain files that are held. Here is what it looks like from a Windows computer.

Graphical User Interface (GUI)

Working with ‘LS’

ls is a shell command built-in just like cd, which will list your files and directories from your current working directory. The ls command is a quite common command that is used when needing to view all files. The ls command automatically sorts the files in the directory in alphabetical order if there are no sort flags given on the command line. The contents that are displayed in the terminal using this command can show with different colors. Content titles that are regular files will display in the color of white. Content titles that are directories will display in the color of blue. Content titles that are executable files will display in the color of green. Content titles that are symbolic links will display in the lighter color of sky blue. Content titles that are image files will display in the color of magenta. Content titles that are archived files will display in the color of red. The ls command can be used in conjunction with flags to give you more information on the contents in that current directory.

The -l option can be passed alongside it in some instances. What this option does is format the output this time, in a long list. When contents are displayed using the -l option, it gives detailed information that is attributed to the content.

Another difference you may have noticed here is that the list now contains new pieces of code that display permissions such as: read, write, execute for different users, owner of the file, size in bytes, and the date of the last time you modified anything in your existing repositories.

The ls -l combination can not only be used for the current working directory, but you can also use it to display contents of other directories. If you use the format ls -l /pathname, it will display the detailed information. The “–” symbol is used to let the system know that it would be looking for regular files. The first section of each file will contain a possible combination of {“-”, r, w and x}. The first group of combinations are permissions given to the user, the next group is permissions given to the group & the last group gives permissions to others. The r represents that the file has the assigned group and has the proper permissions to be able to read the file. The w represents that the file has the assigned group has the proper permissions to be able to write to the file. The x represents that the file has the assigned group and has the proper permissions to be able to execute the file.

The number immediately after this counts the number of links if the content is a file. If the content is a directory, it adds the sub-nodes to the count. The name that displays in the next section to the right would be the owner of the file. Continuing to the right this information displays which group the file belongs to. The next section lets you know how big the file is in bytes. After the size is date section that displays the information about the last modified or creation date as well as the time the change or creation occurred. The last section on the line displays the filename.

Now… in order to add the *.c option we will need to open a repository or directory because this will list specifically all of our .c files that can be compiled using the GCC compiler and inevitably return back to us an object file that is a raw executable. Once the files are compiled into an executable file you can run the file in the terminal by using the syntax ./filename.

What REALLY Goes Into It?

There are a series of steps that go into play when a user types a command into the Shell. Those steps are: Parsing, Checking for Aliases, Checking for Built-In’s, and Execution.

Step One:

Parsing is is the process of analyzing a string of symbols. In order to configure the user input, a function called strtok(), then begins to parse the command into tokens. When using the strtok function it uses the parameters of the string that needs to be parsed and well as a delimiter. The delimiter lets the system know where to end each token. Some of the common delimiters are: /, : , etc. Now, ls -l will tokenize into an array of strings containing [“ls”, “-l”]. Each token will be evaluated individually.

Step Two:

The Shell will then check if any of the commands are either a built-in or an alias. If any of the tokens are an alias, they are converted. If the token is a built-in, the shell can run the command given at the first index position of the array.

What is an Alias?

It is essentially a shortcut for a command. It can be used to be more efficient and avoid typing long commands. They are typically stored in a file like, .bashrc. There are two different types of aliases that can be created, a temporary or a permanent. An alias can be created on the command line in the terminal. In order to create an alias, you would type alias followed by a space and the name that you would like to give your alias. Following the name, you would type in “=” and quotation marks. In between the quotation marks you would type the command that you want to run when you use the newly created alias. This will create a temporary alias that can be used during your current terminal session.

In order to make your alias a permanent alias, you would have to save in one of the config profile files. The available shell configuration profile files would be bash (~/.bashrc), ZSH (~/.zshrc) or Fish (~/.config/fish/config.fish). Sometimes it is necessary to delete your permanent alias and the process can be done one of 2 ways. The first way is to type in the terminal line unalias followed by the alias name. This removes a single alias from the system. You can also go into the shell configuration profile file that you saved the alias in. Delete the line that contains the alias that you no longer need, save the file and close it.

What is a Built-in?

These are commands, moreover “functions” that are a part of the Shell. The function would run and pass all its arguments, then return back again for the next input (this would be done in a file containing a do-while loop).

Fun Fact: Entering type and then a command will let you know if it is either an alias or a built-in function.

Step Three:

The command will be compared to the PATH. This is an environment variable that specifies a set of directories that contain executable programs.

“The /bin, /usr/bin, and /usr/local/bin directories are typically included in most users’ $PATH” -Wikipedia

The directories contain all the commands a user can enter. The fork() function (also a system call) creates a child process that duplicates the environment straight from the parent process, and begins to run then eventually close itself, and return back to the parent process.

The command can now be executed using execve() function and we should receive our expected output, listing all files and directories in long format!! As you can see, The Shell undergoes a lot of analyzation before we receive what we are looking for. It’s not so simple after all. Thanks for reading along.

Written by: Bree Browder and Nikki Edmonds

Student at Holberton School

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store