This article was organically contributed by monk.
When you are logged in to a Linux server and you type a command. It is the responsibility of the shell to interpret your command. Here I will explain how BASH shell finds out which program to run. The method used by SHELL is straightforward but often creates confusion for new Linux user/admins/Interns.
Remember your shell deals with different commands and command line options to process your request.
- Internal commands aka shell builtin command (such as set)
- External commands (such as clear, date)
- Aliases (such as alias rm='rm -i')
- Command substitutions ( such as echo "Today is $(date)")
- Pipes ( such as cat /etc/passwd | wc -l)
- I/O redirection (such as cat /etc/passwd > /tmp/names)
As you can see, SHELL has to do many things before it can find the correct executable file for you. For example, when you type single command date; SHELL will locate date command for you. Then it spawns (forks) a new process and "execs" the date command. Please note that discussion related forks and kernel is beyond the scope of this document (see nice explanation by Tony @ How shells call other programs). Here you just want to understand how Linux knows which program to run.
Shell uses PATH variable
Your shell uses the environment variable called PATH to locate commands. Just type following command to display your current PATH:
$ echo $PATH
The variable PATH defines search path for commands. As you can see, PATH holds a colon-separated list of directories in which the shell looks for commands. Returning to the date example, when you type date command, shell will start with the directory on left (i.e. /usr/local/bin) side of PATH variable and checks to see if there is date command executable file. If executable file found, shell will execute date command. If command cannot be located at all in all directories then you will see command not found error message. BASH shell use following sequence to execute command (for example purpose, we will use date command):
- If there exists a shell FUNCTION date() execute it and stop.
- If there exists a shell builtin date command, execute it and stop
- If the date is neither a shell function nor a builtin then BASH searches in HASH tables. If there exists an entry for date command execute it and stop.
- Finally, if date does not exist in HASH tables, it will search using PATH variable.
- If above all method fails then SHELL will return error "Command not found" and always exit with 127 status code.
However, things started to get complicated if it is a shell script, the SHELL does exactly the same thing (as mentioned above), but the exec fails, which causes the shell to read the script and interpret it.
What is a HASH table?
A HASH table is nothing but some sort of caching mechanism to speed up things. For each command, the full file name of the command is determined by searching the directories in $PATH variable and remembered by shell in HASH table. Just type hash command and it will display the all remembered directory name:
Related shell commands
To solve a command searching mysteries Linux/SHELL offers couple of commands.
Tells whether command is an alias, function, buitin command or executable command file. To be frank type command indicate how it would be interpreted if used as a command name. General syntax:
$ type -a ls
ls is aliased to 'ls --color=auto'
$ type date
date is hashed (/bin/date)
$ type dirs
dirs is a shell builtin
$ type if
if is a shell keyword
$ type getip
getip is a function
lynx --dump 'http://localhost:81/getip'
Use to locate a command in a PATH.
$ which ls
Continue reading the second part of "How Linux or UNIX Understand which program to run" series (this is part I).
- PART I : How Linux or UNIX Understand which program to run
- PART II : An example: How shell Understand which program to run
Updated for accuracy by Vivek. This article almost rewritten to fix typos.