What happens when you type ls -l *.c and hit Enter in a shell?
The ls command (list) is a command line interface (CLI) tool that belongs to the Unix operating system, such as GNU/Linux and its distributions. This tool allows us to list the elements in a file system: directories, links and types of files contained in a given directory. The results are displayed by default sorted alphabetically and by standard output.?In GNU/Linux the ls command is commonly used for this type of queries. Although it is not the only one, there are other CLI tools that are equivalent, including the dir command as an alternative to the ls command.
The ls command offers the use of flags/options, which allow the generation of a list of different forms and details. The ls command corresponds to the following syntax.?
ls [OPTION]... [FILE]...
The ls command, executed directly and without any parameters, will only print the names of the files and directories contained in the current directory as shown in the following example:?
However, it also allows us to visualize, with all its options, the contents of folders that are at another address without moving from the position in which we are. For this we must indicate the path of the folder from which we want to obtain information, for this, we enter the command ls followed by the path of the folder from which we want to obtain information.
In this example we will ask from the user's folder, to show us the content of the simple_shell folder, whose address is /home/vagrant/simple_shell:?
$ ls /home/vagrant/simple_shell
Next we will see one of the most commonly used ls command options and the information it gives us by standard output. It should be noted that although we are only going to talk about one of the many options of the ls command, it is possible to use more than one simultaneously obtaining different combinations of these.
List the contents of a directory in detail
The ls command followed by the -l option prints (displays) an alphabetical list in detail of the files and/or folders in the directory in which we are located. According to the syntax mentioned above, to use this flag we only need to type the following:?
$ ls -l
The result obtained can be seen in the following example:?
The information in detail that is divided into columns from left to right indicate us:
List only files with a ".c" extension.
As we know, in almost any search engine we can use wildcard characters to facilitate a query. For the case of LINUX, the character "*" means to match any character in a file name, that is to say that it expands the files that match what is given to the wildcard. With expansion, we type something and it expands into something else before the shell acts on it, in other words, when the enter key is pressed, the shell automatically expands any qualifying characters on the command line before the command is executed.?
So, if we want to list in detail all the files in a directory whose extension is .c, we must use the following command line:
$ ls -l *.c
Where, ls - l corresponds to the command you want to execute with its respective option and * .c is the wildcard that expands in the current directory all files ending with the extension .c as we can see in the following example:
领英推荐
But what happens when we type ls -l *.c and press Enter in a shell ?
To understand this process, we must keep in mind that shell has standard input/output file descriptors connected to the terminal, such as standard input, standard output and standard error. So through the standard input, we are sending shell the command we want to be executed when we press Enter.
Once we press Enter the following happens:?
1. Expansion *.c:
Well, as we mentioned earlier, before the shell executes the command, it expands what is pointed to by the wildcard "*", so the first thing that happens is that it replaces the *.c with a list of all the files in the current directory that have .c in them.
2. Splitting the command into tokens:
When we enter characters in our terminal, the keyboard driver discovers it and sends it to shell as a complete string, which is divided into tokens, such division is done taking into account spaces and tabs within the string. This process is called tokenization.?
At this point we will have two tokens corresponding to the ls and -l command and the token corresponding to the *.c expansion.
3. Check the aliases:?
At this point, we check if there is any alias assigned to the command, if it exists, we replace the token with the corresponding command, tokenize again and check again if there is an alias until it is no longer found. These are retained until the terminal session is terminated, but are usually added to the shell configuration file (~/.cshrc or /etc/csh.cshrc (system-wide) for csh, or ~/.bashrc or if you want to system-wide /etc/bashrc or /etc/bash.bashrc for bash) making them available to all terminal sessions.
4. Check the built-in plugins:
Now it is checked if the tokens are built-in, that is, it is validated if it is a function or command called from shell, these are executed directly in the shell, unlike the non built-in ones whose executable file exists within the PATH and must be searched in this to be executed as is the case of the ls command.
?5. Find the command in the PATH:
Because the ls command is a non-built-in, its corresponding executable file must be searched for within the directories of the PATH environment variable. This search is performed by calling a series of functions such as find_user_command(), find_user_command_in_path(), find_in_path_element() and bash invokes the stat() function to validate if a matching executable file exists in each directory of PATH.
6. Call the ls -l program with all filenames ending in .c as parameters:
Obtained the full path from the ls -l command, bash sends the result obtained to the execve() function so that it executes it inside a child process spawned by fork(). In order for the directories and files entered as parameters to the ls command (in this case all those expanded by *. c) can be read, a list of functions and system calls are executed internally to achieve an output, among them the opendir() function to open the directory, closedir() to close it and readdir() which reads the list of files in the current or pointed directory to query the inode entries of the underlying file system and deliver the details generated by the -l option and as soon as the command has been executed, the entries are retrieved and the syscall returns.
7. Finally, when ls finishes, it prints the prompt, using PS1:
PS1 is an environment variable that governs the default interaction command prompt, it represents the primary prompt string that is displayed when shell is ready to read a command. As soon as ls finishes, it prints the prompt again, which is stored in the environment variable PS1 and the list of files is returned to the prompt, which finally waits for a new command to be entered.
Authors:?
Juan Sebastian Perea Bescos - https://twitter.com/JuanSePeBe95 -https://www.dhirubhai.net/in/juan-sebastian-perea/
Sandra Calero Casta?eda - https://twitter.com/SandraC59631923 - https://www.dhirubhai.net/in/sandra-liliana-calero/