What's behind pressing ls -l *.c in the shell
Simple shell simulation (sh). Own Authorship

What's behind pressing ls -l *.c in the shell

Shell management is not as complicated a matter as many people would believe. The dark appearance, the white letters and the little information that can be seen at first glance when running a shell (like the Bourne shell, sh), possesses a "power" beyond its shy $ sign displayed on the screen. Basically, the “superpower" of the shell lies in the great ability it has to interpret commands and have them executed at the kernel level of the operating system with the implementation of special functions to execute system calls.

No hay texto alternativo para esta imagen

In this blog, we will talk a little bit about what happens behind just expressing in a command line interface, a command like ls -l *.c.

To begin with, it is necessary to talk a little about the system calls, because its mechanism is simple and consists of accessing the kernel services taking into account the processes that are being carried out. Why talk about the system calls? because the symbol $ that shows the shell, is called "command prompt", so when a person enters in the shell the command ls -l and presses enter, you would see something similar to this:

No hay texto alternativo para esta imagen

This is what it shows us, what comes up on the screen when that command is executed, but the question has not yet been answered, what is really happening in our system, when through the shell, that command is executed?

Step by step

Let's go step by step and try to understand what is happening. The images accompanying this blog are part of the "simple_shell" project which you can access by clicking here.

1.Choosing the shell's operating mode and initialization

When we refer to choosing the operating mode, it is because we recognize that there are two ways of interacting with it: interactive and non-interactive. The one differs from the other, according to the way we want to choose to work with it. In the first one the prompt remains after executing a command, on the contrary in the second one, you execute only once what you want to do in the shell and the prompt does not appear anymore because the command has been executed only once.

No hay texto alternativo para esta imagen

If you decide to work in interactive mode (as shown in the image above) you will have an executable ./hsh that is generated from a previous compilation of all the files. This, in the background, is generating an infinite loop in which many things can happen when typing a command there.

2. Reading the command

Once you have decided how to use the shell and type the command, the shell reads what you typed using the getline() function which reads the line you enter as a string from the standard input (stdio) to be stored in a buffer, which is a memory address that can be accessed by a pointer.

3. Answer Is what I entered in the shell a valid command?

No hay texto alternativo para esta imagen

To answer this question, it is necessary to understand that commands can be entered incorrectly (for example, with many spaces) and that the shell is able to organize that input so that it can fulfill its function of being executed.

The strtok() function will take care of this by making use of the pointer created earlier and tokenizing that entry to be stored in an array of pointers as follows: "ls -l" will become "ls" "-l", where array[0] corresponds to "ls".

4. Checking the first argument of the array of pointers

Now that you have tokenized what you entered for standard input and have something like array[0] = "ls", that "ls" will be looked for, first of all, in the shell's built-in commands. If it is not found there, it will look for it in the $PATH (environment variable) and finally, if it is not found in either of those two places, it will look in the current directory where the ./hsh is executed (more about absolute paths and relative paths)

If it is definitely not found in either of these places, the shell will return an error message indicating that the file or directory was not found. Knowing whether or not it is found is done by the stat() function.

5. Execute command

When an executable has been found, the interpreter executes the fork() system call to create a new child process of the parent in order to keep the shell running (in interactive mode) in parallel without causing the termination of the main process (the parent). Here use is also made of the wait() system call that is used to put the parent on hold while the child process runs. While the child process continues, the file is executed with the execve() function and will be displayed on the screen. Finally, if you want to terminate the child process, the exit() function is used.

No hay texto alternativo para esta imagen

6. I got what I wanted, it's time to exit.

By this point, the shell will have served its purpose, it will have executed all these system call functions and you will get in the standard output what you wanted according to the command you typed. If you are in interactive mode, there are three ways to exit the command line interpreter: by pressing CTRL + d, which indicates "end of file" and whose value is -1 because it must be different from any other return value; by pressing CTRL + c, which will send a signal to the process trying to end it in a proper way; finally, by typing "exit".

Only if the whole process ends with an exit (0) indicating that it has ended correctly, it returns to the parent process cleaning the memory allocations that were made with the child processes, a line break is made and the prompt reappears, and everything can happen again if you want to continue interacting in the shell.

This flow is handled for any case, here we illustrate it with ls -l, but we invite you to think how it would be with other different commands, would the same thing happen? what does our shell do when something is entered that it will never manage to find? to what extent do I have control of what is happening in the shell?

Authors: Diana Parra and Brian Zapata (Holberton School students)

More information:

  • Visit our own implementation of a simple shell in GitHub
  • The Linux Programming Interface: A Linux and UNIX System Programming Handbook-Michael Kerrisk (you can read it here)


要查看或添加评论,请登录

Diana Parra的更多文章

社区洞察

其他会员也浏览了