Shell provides an environment to the user where the user can execute multiple executable programs and the output of those programs is displayed on the display. Basically, the working philosophy of the shell is that it continuously waits for the user to input the string. Then, this string is searched and matched with the known executable programs that are present in the shell environment. If the matched, executable program is found, the executable is launched after creating a child process. This newly created child process executes the program. The output of the program is handed over to the parent process which is shell. Shell prints the output to the console if the output is not redirected. The locations where the shell searches for the executable programs is present in the environment variable, “PATH”. PATH variable keeps the “:” separated in several path where shell searches for the executable programs.
The block diagram for the shell is shown in the following:
From the provided block diagram, we can conclude that we need a shell to execute any C executable in Linux environment. Without the shell, it is not possible to execute the C program dynamically. There are some predefined executable programs which are known as the shell commands. Some examples of the shell commands are ls, ps, etc.
Let’s discuss the shell commands. There are two types of shell commands:
a) Built-In Commands
These are the commands which are the part of the shell itself. While executing these commands, shell doesn’t fork. These commands are executed as a part of shell itself. To update in these commands, we need an update in the shell itself. These commands are tied with the shell.
Some examples of the built-in commands are cd, echo, kill, break, alias, bg, etc. We can use the “help” command to see the whole list of built-in commands.
b) External Commands
These commands are the separate C program executables. These are not part of the shell. These are places at specific path. Shell looks out to those paths, executes the programs, and displays the output. Adding a new command to the list of known commands is easy; just copy a new executable program/command to the known path. Generally, these commands are placed in the path like /usr/bin, /usr/sbin, etc. All the locations are specified in the PATH.
In my system, the known path to the shell which is the echo command can be checked to get the complete list of the path:
If we want to introduce a new path to this list, we can update the values to the PATH environment variables. The “export” command can be used to update the PATH with the new values.
Using the “type” command, we can get that any command is built-in or external. Let us understand the usage of “type”. Executing the type with “cd” gives the following output:
cd is a shell builtin
The output of the previous command is self-explanatory.
Now, let us try the “type” command with lspci command:
lspci is /usr/bin/lspci
As the output shows the path of the executable, we can conclude that this is an external command.
There are few environment variables that are defined for the shell. Until now, we understood the PATH variable. PATH is an environment variable which provides the list of path to be searched for external commands. The complete list of environment variables can be checked with the help of env command. The env command provides the complete list of environment variables.
Some few examples for the environment variables of shell are:
- PATH: The list of paths for external commands.
- SHELL: The type of shell which is currently active.
- OLDPWD: The last working directory.
- PWD: Refers to the Present Working Directory.
- USER: The username for the active shell.
- HOME: The home directory for the user.
There are many more. As discussed previously, the complete list can be checked with the env command.
Changing the Environment Variables
The needed values can be directly assigned to the variable, as shell allows us to use the assignment operator. The current value of any shell variable can be seen with the help of the echo command. For example, if we want to check the value of the PATH. Executing the following command should be able to do so:
Using the $ operator before the variable inside the shell prints the value of the variable. This is the offering of the echo command. Similarly, echo can be used to print any environment variable.
If we want to update the PATH variable, we want to update the custom path like /usr/cutom which we want to add to the PATH. We place our cutom commands at this path. In order for the shell to execute these commands, its value needs to be updated in the PATH. Without updating the PATH if we execute these custom programs, we get the error saying, “no such file or directory”. This error clearly says that the shell is unable to locate the commands.
As an experiment, we pplace our custom command, myls and myps, in the /home/srathore/custom. When we execute myls or myps from /home/srathore, we have the following message from the shell:
Command 'myls' not found, did you mean:
command 'tyls' from deb terminology
command 'mmls' from deb sleuthkit
Try: sudo apt install <deb name>
Command 'myps' not found, did you mean:
command 'mypy' from deb mypy
Try: sudo apt install <deb name>
The previous messages show that these commands are not found and a suggestion is given by OS to install these commands.
Now, let us add the new custom path to the existing PATH as follows:
srathore@srathore:~$ export PATH=$PATH:/home/srathore/custom
srathore@srathore:~$ echo $PATH
Our newly added path is highlighted in bold. We can see that the PATH environment variable is updated with the new value.
Now, let us try again to execute the commands that are present in our custom path. By executing “myps” and “myls”, we have the following output:
PID TTY TIME CMD
2112 pts/0 00:00:00 bash
2783 pts/0 00:00:00 myps
a.out pack-installed spd_tool build_root_fs kernel_articles patches stime
coreboot kernel_ubuntu pcie_transfer_app stime.c
bash_arm custom lmsensors Redfishtool telnet_scripts nvm_cli
The previous logs show that both commands worked perfectly. We did not have any error as we observed before updating the PATH variable. We discussed the most important shell variable, which we generally modifies in our day to day development work. If we install any new package, this variable is updated so that the new tool commands can be easily located by the shell.
We discussed the definition of shell. We also seen the philosophy behind the shell implementation of the different types of commands provided by shell and the environment variables of the shell. We have also gone through few environment variables. Most importantly, we discussed about the PATH variable. We have also seen the way to update the PATH and the importance of the variable which is demonstrated by an example. We learned the importance of shell and its offerings.