What happens when you type ls -l in the shell

lsis a relatively simple and straightforward command. But what actually takes place behind the screen will get you to appreciate how little work is required from you to acquire the output you desire.

I will show you what is happning behind the screen.

ls is the most basic command of Linux. It list information about the FILEs (the current directory by default).

ls command examples:

1- Listing files:

$ ls

2- List directory with relative path

$ ls /home/user

3- List root directory:

$ ls /

4- List parent directory:

$ ls ..

5- List user’s home directory (e.g: /home/user):

$ ls ~

6- List with long format:

$ ls -l

7- Show hidden files:

$ ls -a

8- List with long format and show hidden files:

$ ls -al

9- Sort by date/time:

$ ls -lt

10- Sort by file size:

$ ls -lS

11- Recursive directory tree list:

$ ls -R

12- Display file size in human readable format:

$ ls -lh

13- Display directory information

$ ls -ld /etc

14- Display hidden files without . and ..

$ ls -A

15- Display inode no

# ls -I /user/home/Documents

Those are all the ls command possible.

We going to get deeper just with the -l option, ls will list out files and directories in long list format. You will encounter something like this:

Displaying file type, permissions, owner, size, date of creation, and file name.

To understand how shell interprets a user’s input, it helps to get a basic understanding of how an operating system is organized.

The kernel is the central, most fundamental part of a computer operating system. It’s a program that controls all other programs on the computer, talking to the hardware and software, highly involved in resource management.

The shell is an application, one of the two major ways of controlling a computer (GUI the other). It is the way a user talks to the kernel, by typing commands into the command

What happens when you type ls -l and hit enter (Deeper):

Steps to processing a user command:

  • Get the user input
  • Check for expansions and alias.
  • Check the builtins.
  • Check the PATH.
  • If file exists: fork and execute program in the child process.
  • After child process terminates, parent process will print prompt to user.

Get user input:

Upon entering shell, we will encounter the prompt(prompt string 1, or PS1). After you input ls -l to the command line, shell reads ower input by using getline() (man 3 getline). Getline reads from the standard input file stream, STDIN, and stores the user input into a buffer as a string.

The buffer(containing the input "ls -l") is then broken down into tokens and stored in an array: {"ls", "-l", "NULL"}. args[0] = "ls", args[1] = "-l", args[2] = "NULL"

Check builtin:

If ls is not an alias, shell will then check whether the command ls is a built-in command. A built-in command is a command that is built into and executed in shell itself. Examples: cd, alias,echo, help, read, type setenv,unsetenv

Check PATH:

Then, the shell looks for a program file called lswhere all the executable files are in the system — in the shell’s environment (an array of strings), specifically in the $PATH variable. The PATHvariable is a list of directories the shell searches every time a command is entered. PATH, one of the environment variables, is parsed using the ‘=’ as a delimiter. Once the PATH is identified, all the directories in PATHare tokenized, parsed further using ‘:’ as a delimiter.

The tokens are delimited by a colon, so here, the user input will be checked against /usr/local/sbin, /usr/local/bin, usr/sbin, usr/bin, etc.

/ls will be appended to the end of each token: /usr/local/sbin/ls , /usr/local/bin/ls, etc.

After searching through each token, an error will occur if ls is not an existing file.

Check for expansions and alias:

Prior to searching for the ls command, shell will check for special characters that need to be expanded(i.e., *, $, etc). For example, if the user input is ls *.c, this is when *.c will be replaced with all .c files within current directory. Shell also checks for aliases(an alias in shell is similar to a keyboard shortcut). If ls is an alias, shell will replace ls with its corresponding value here. Say we set up an alias called al_cat: alias al_cat="cat". After entering al_catmain.c, our command will be processed as cat main.c.

Fork and execute program in the child process:

Upon locating the ls file in PATH, shell will open and run the file ls by calling fork(). fork() is a system call creates a clone of the current process. All user processes on a Linux system stem off as a result of fork(). Both of the processes will run the instructions following fork(). So to distinguish from the two processes,fork() returns the child’s process id to the parent, -1 to indicate an error and 0 in the child process .

  • Shell(calling process/parent process)will call fork() to create a copy of itself(child process). The clone/child process will have its own system process “ID”. Running a program in a separate process protects the parent/current process should the program cause any problems upon execution .
  • The child process then calls execve() to run the user’s command,ls. execve() will replace the current(child) process with the program it calls( ls, in this case).
  • Parent process waits until the child competes its execution via wait().

Upon completion, the child process will terminate and control will be returned back to the parent process. We will be greeted with the prompt once ls is executed and will be able to enter the next command .

References:

http://www.makeuseof.com/tag/linux-kernel-explanation-laymans-terms/

https://brennan.io/2015/01/16/write-a-shell-in-c/

http://www.linfo.org/usr_bin.html

https://vedslinux.blogspot.com/2013/10/linux-ls-command.html

Tunisian software engineer