By default bash is the default shell in Linux. Lets see how bash shell interprets the command we type in.
It not as simple as checking the binaries in directories specified in the $PATH variable. It flows through the following steps:
- Redirection
- Aliases
- Expansion
- Shell Function
- Shell Built-in
- Hash table
- PATH variable
Lets go through the steps :
1. Redirection.
This comes into picture when you use redirection : ">" and ">>".
You can see that a file list.txt is automatically created before the "ls" command is executed with redirection ">". How does this happened ? Redirection is done and the o/p file is created before the command "ls" is executed.
2. Alias.
Alias is actually shortcuts or easy to remember alternatives of a command.
Here we have defined alias "ls=cat", now when we type "ls list.txt" , ls is replaced with cat and contents of list.txt file is displayed.
Just FYI, we can make the shell ignore alias by preceding "\" with the command.
3. Expansion :
Expansion stands for command substitution, variable and parameter expansion, tilde expansion, brace expansion, arithmetic expansion, word splitting, and path name expansion.
Like this ~, *,? etc will be replaced accodingly.
4. Functions defined in the Shell
Shell also allows to define functions like other programming languages. After defining functions you can execute it just like any other commands.
As you can see, here I have shown you the order of interpretation. Alias has precedence over Functions!. When we first executed "ls" the alias /bin/ls is executed. Then ignored alias with "\" and function is executed. Then we deleted the alias "unalias" command. Now since there is no alias, text candidate to run is function.
5. Shell Builtin
The bash code contains some commands as well. These commands gets precedence over other binaries. The type command can be used to identify who the command is interpreted.
Lets play a bit with this :
[jk@rhel1 ~]$ type echo
echo is a shell builtin
echo is a shell builtin
[jk@rhel1 ~]$ which echo
/bin/echo
[jk@rhel1 ~]$ type ls
ls is a function
ls ()
{
echo "I am a Function"
}
[jk@rhel1 ~]$ alias ls="echo GNU/Linux"
[jk@rhel1 ~]$ type ls
ls is aliased to `echo GNU/Linux'
[jk@rhel1 ~]$ ls
GNU/Linux
GNU/Linux
[jk@rhel1 ~]$ unalias ls
[jk@rhel1 ~]$ ls
I am a Function
[jk@rhel1 ~]$ unset ls
[jk@rhel1 ~]$ type ls
ls is hashed (/bin/ls)
[jk@rhel1 ~]$
I shall explain why "hashed" is displayed in the last command.
6. Hash Table
The concept of hash table is similar to cashing in Linux, shell store the full path of all the executed commands to speed things up.
Lets see how hast table works. We have started a new shell and executed "ls", "cat" and "echo" commands. Then we checked the hash table entries. The hash table, as already mentioned, contains two columns, first column contains the cache hits and the 2nd column contains the full path of the command. Also note that the shell built in command "echo" is not listed in the hash table. Remember the purpose the hash table is to speed up the execution.
You can see that when the command "ls" is executed the second time, the hits value is increased.
7. Path Variable
After all the above steps are over or not available, shell searches for the given command in the directories specified in the PATH variable.
[jk@rhel1 ~]$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/jk/bin
[jk@rhel1 ~]$
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/jk/bin
[jk@rhel1 ~]$