The mystery of how shell commands works
what happens when you type ls -l *.c in your terminal
You are curious and obviously want to take control of your computer on a nitty-gritty level, you want freedom and that’s why you decided to read this blog. My definition of freedom is to choose to do anything you want which in this context, it means to decide what to do with your computer by knowing exactly what your computer does. Most of the time this involves working with your command-line interface (CLI).
The CLI helps you to communicate expressively with your computer which in some cases wouldn’t have been possible with Graphical User Interfaces (GUI). Shell is responsible for taking the commands you type with the keyboard on the command line and passing the command to the operating system (OS). This blog post is centred around the Linux OS, however, we need to understand some terms or things that make up the Linux OS at the time of this writing I’m using Ubuntu 20.4 LTS distro, everything mentioned in this writing is applicable to all Linux operating system distributions.
Unix
Let’s dive a bit into Unix Shell. The UNIX shell is a command-line interpreter that provides a command-line user interface for a Unix-like operating system (OS), the shell can be utilized or worked with in two different ways either in the interactive mode or as a scripting language and the operating system uses the shell script to control the execution of the system, to use the interactive mode or session, you need a terminal emulator which gives you many choices of command-line interpreter you want to use. For instance, when you log into your system a shell program will automatically be executed for the duration of the session. you can customize the type of shell you want to work in, to do this you need to modify your profile which is the user’s profile.
this brings us to mention the different types of shells, which are:
Bourne shell (sh) with pathname bin/sh
Bourne Again Shell (bash) with pathname /bin/bash
C shell (csh) with pathname /bin/csh
Korn Shell (ksh) with pathname /bin/ksh
Z shell (zsh) with pathname /bin/zsh
Let’s focus on the second one, the Bash shell which is the default shell for almost all Linux distros, it is an enhanced replacement of the original Bourne shell and it has the features of different shells such as C and Korn Shell, it also allows you to easily recall previously used commands with the up navigation button on your keyboard. With the bash shell, you can literally navigate around your files with these basic commands pwd
, cd
, ls
.
pwd
: stands for print working directory, this command helps you to determine the current directory you are in or working on
cd
: stands for change directory, this command helps you to change directory which means you can either leave a current working directory to another.
ls
: stands for list files and directories, and when combined with some flag options you can even get to list more information about each file or directories.
But before you check out any of these commands, let’s understand and examine how the command gets executed or how it works in the background.
in the image above, we are about to run the ls command but let's try to understand how the shell goes about executing the command. The moment you typed the command ls
right after the displayed prompt #
and press enter button on your keyboard, the first thing shell does is, it tries to match the keyboard input with the alias-defined system.
The alias command makes it possible to launch any command by entering a pre-set string.
After matching, the text (which is the command ls
typed earlier on) is replaced with the alias before the shell proceeds to search for the command, then the shell checks if the first word of the input command represents a built-in command, these are commands which are contained within the shell itself, the shell will always proceed to match the input command with a process identifier if it fails to identify a built-in command.
A process identifier which is usually referred to as PID is a number used by the Unix-like operating system kernels to uniquely identify an active process, this number can be used as a parameter which can be passed to a function or could be as well used to manipulate processes. So while shell searches for a command, it also searches for the command’s PID in another environment variable PATH till it finds the particular identifier directory. Once the command PID is found it automatically run the executable file of the PID which in this case list all the files and directories.
Having understood all the above information, it will become easier to understand what happens when you type ls -l *.c
in the shell.
Let’s break this a bit further the -l
is a flag option the shell uses to list file and directories permission levels such as the rwx attributes. The image below depicts the effect rwx has on files and directories.
The image above depicts the permission attributes.
the *
is called wildcard pattern matching notation which is used to match any characters but the order of precedence and how it is used matters, in this context, it means all filenames with a file extension. C (all files written in C code), having explained all the above information the output you get when you run the command ls -l *.c
in a shell is similar to the output in the image below depending on the files you have in the current working directory.