ls -l *.c command line

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

Ahlemkaabi
6 min readApr 12, 2021

--

Hello friends, today you will know what actually happens when you type ls -l *.c in your terminal.

Terminology

let’s start from the beginning, there is a few key words that you need to know.

Terminal

Way back when computers were huge multi-user systems owned by universities and corporations. The machine itself was located in a secure room that ordinary users didn’t visit. Instead, they interacted with it via a terminal. In the early days, the terminal would have been a printer (a teletype, hence TTY). The input was via punch cards and output via a printer. Later, a terminal was a display with a keyboard. (more about punch cards!)

Today’s terminals are software representations of the old physical terminals, often running on a GUI. It provides an interface into which users can type commands and that can print text. When you SSH into your Linux server, the program that you run on your local computer and type commands into is a terminal.

Shell

The broadest definition of a shell is a program that runs other programs, but when you hear shell in the Linux world, it almost certainly refers to a command line shell — the program that creates and manages the command line interface into which users type commands.

For example, when you type “ls” into a terminal connected by SSH to your Linux server, you are asking the shell to run the “ls” program and to print out a list of files in the current directory to your terminal. The shell also provides a programming language of sorts, shell script, that can be used to tie together multiple commands.

The most common shell is Bash, the Bourne Again Shell, but there are several variants; Ubuntu uses the Dash shell, and some Linux users prefer the Fish or ZSH shells.

System calls

When you want to understand what’s happening under the hood of a command line, you probably need to know about system calls.
A system call is a mechanism that provides the interface between a process and the operating system. It is a programmatic method in which a computer program requests a service from the kernel of the OS.

brief explanation of the command

1/ ls: the ls command is a basic command in Linux used to List files and directories. ls command comes with so many arguments and features like you can sort files and directories by Date, by Size, able to check hidden files and directories, permissions, inode information and so on.

2/ -l: this is one of the ls command arguments (options) which means to list files using a long listing format

3/ *.c : means it matches all files that end with “.c”
* is called a Wildcard (also referred to as meta character): symbol or special character that represents other characters. You can use them with any command, such as in our case, to list files matching a given criteria, receptively.
read more about Wildcards.

Now, what happens under the hood?

Split input

The first step is tokenization. The shell has to interpret the single string ‘ls -l’ which we then pass to a function that splits up the string into separate ‘tokens’. In this example, ‘ls -l’ is composed of two tokens, ‘ls’, and ‘-l.’ To do this, we use strtok(), a function that parses strings by a specific delimiter, i.e. a space, or a colon. In this case, we split the tokens by using the space between ls and -l as a delimiter. This function replaces those found delimiters with a special character called null terminators which separates a single string into separate strings (tokens), allowing them to be easily pushed into an array of strings. So, in our example, the original string, ls -l, now is a matrix pointing to the first string ‘ls’ and a second string ‘-l’, followed by NULL terminator signifying the end of the matrix.

Check for aliases

The shell will run through each alias it has on file and if the first argument matches the name of that alias, it replaces it with the alias. It will run through one more time to check for another alias, rinse, and repeat until there are no more aliases. aliases for BASH can be found in a file called bashrc in the home directory.

Replace variables

This is pretty much the same process as alias replacement. It replaces variables it finds, such as $PATH, $?, *, etc, with the corresponding values.

Replace Builtins

Builtins are command that are hard coded into the shell Once the arguments have been converted properly, the shell compares the first argument with a list of strings hard coded into the shell. If it matches any of these strings, it runs a function that corresponds with that string. This is how builtins work.

Execution

And now we get to the fun part: execution! To talk about executing files and running commands, we need to know about the PATH.
The path is a colon-separated list of directories inside of your computer. It is just one string in a matrix of strings stored in a special environment variable .
The environment variable contains data and configuration information that could be useful to an application. try to type env to see the whole environment variables
The PATH is useful because it contains the directories which the shell should look in to find the executable file program .

PATH

In our example, ls is actually just one of the many file programs that is in the /bin/ directory.
When the user inputs a command or program to execute, the shell will look to see if it is in one of the PATH directories: /usr/local/sbin or /usr/local/bin or /usr/sbin etc…
Without the PATH, the user would have to type the absolute path of the program to execute it, in this case /bin/ls — in order to execute the ls program.

same output ls and /bin/ls

There are a couple of different ways to go about checking a file’s existence, and further, checking its accessibility and if it’s executable. No matter how the programmer goes about it, what ends up happening is ‘ls’ is attached to directories in the path until it finds the executable file it was looking for. For example, ‘/usr/bin/ls’ is an executable file.
This finally gets to the part we’ve been waiting for! The shell will fork another child process and run a system call execve with the program path and it’s argument.
Why fork ?? imagine if the program exits do you really want your shell to exit too. The shell has done its primary job. So now what? Well, now that the ‘ls’ program has run, and the file’s contents are printed out onto the prompt using PS1 (), the shell resets itself and is ready to run again. How the shell works on a high level is that it’s constantly stuck in an infinite while loop. That’s why we can continue to run command after command after command. It will continue waiting on commands unless a close signal is struck.
Bonus information: you can actually see all system calls ran by the ls command, just type strace ls. (you can notice one of them ran by the shell, which is execve).

Conclusion

This is a 101 about how the shell works, of course it’s still doing a lot of other things related to memory, access verification, file descriptors and many more.

Authors:

Alaedine Boufaden — Alaedine’s blog
Ahlem Kaabi

--

--

No responses yet