The shell searches for the commands you type by name in a list of directories of commands, e.g. when you type "date" the shell goes looking for a file named "date" to execute.
After the shell has processed and removed I/O redirection on a command line, the first token left on the line is assumed to be a command name.
A few built-in commands (e.g. "cd", "pwd", "history") are executed directly by the shell. Anything that is not built-in is assumed to be the name of an executable program, and the shell attempts to find a program with that name and run it. (Shells find and run commands.)
If the name contains any slashes (e.g. "/bin/date", "foo/bar", "./myprog"), the shell executes that pathname directly. No searching needs to be done.
$ echo "$PATH" :/bin/:/usr/bin # EXTREME SECURITY RISK!
$ echo "$PATH" /bin/::/usr/bin # MODERATE SECURITY RISK!
$ echo "$PATH" /bin/:/usr/bin: # SECURITY RISK!
Because PATH is a shell environment variable, you can change it, and it is usually exported and inherited by child processes of your shell.
How it works:
$ PATH=/bin:/usr/bin ; ls - shell tries to find "ls" in first directory in PATH: /bin - shell looks for /bin/ls - this exists, so it is executed
$ PATH=/bin:/usr/bin ; gcc - shell tries to find "gcc" in first directory in PATH: /bin - shell looks for /bin/gcc - this is not found - shell tries to find "gcc" in next directory in PATH: /usr/bin - shell looks for /usr/bin/gcc - this exists, so it is executed
$ PATH=/bin:/usr/bin ;nosuch - shell tries to find "nosuch" in first directory in PATH: /bin - shell looks for /bin/nosuch - this is not found - shell tries to find "nosuch" in next directory in PATH: /usr/bin - shell looks for /usr/bin/nosuch - this is not found - shell issues message "nosuch: Command not found"
$ PATH=/bin:/usr/bin ; /usr/games/fortune - command name /usr/games/fortune contains slashes, $PATH is NOT used - shell executes /usr/games/fortune directly (if it exists) - $PATH is NOT used
$ PATH=/bin:/usr/bin ; ./foo - command name contains slashes, $PATH is NOT used - shell executes ./foo directly (if it exists) - $PATH is NOT used
Your shell has some built in commands, e.g. echo, cd, umask, pwd, history
- built-in commands are not looked up in $PATH
$ PATH=/xxjunkxx ; date # fails (because /xxjunkxx/date fails)
$ PATH=/xxjunkxx ; pwd # works because pwd is built-in to shell
$ PATH=/xxjunkxx ; echo hi # works because echo is built-in to shell
$ PATH=/xxjunkxx ; cd .. # works because cd is built-in to shell More examples:
$ PATH=/bin:/usr/bin ; ls # works because /bin/ls exists
$ PATH=/xxjunkxx ; ls # fails because /xxjunkxx/ls does not exist
$ PATH=/bin/ls ; ls # fails because /bin/ls/ls does not exist
Commands related to PATH: which - tell which $PATH directory contains a command
whereis - locate commands in "standard" directories (ignores $PATH) (also locates man pages for you, if any)
Note that "whereis" may tell you that a command exists in some standard directory, but when you try to execute the command it may not be found, if the standard directory is not one of your shell's PATH directories.
Most shells only look in PATH, not in any "standard" places. If you have a bad PATH, no commands will be found.
Summary: - only command names without slashes are looked up in $PATH - a command name containing a slash is NOT looked for in $PATH - slashes in a command name mean no PATH lookup; direct try to execute path
$ ./a.out # uses the a.out in "."; does not search $PATH
$ /bin/ls # executes /bin/ls; does not search $PATH
$ ../foo # executes the foo in the parent dir; no $PATH used $ foo # "foo" is looked for in $PATH
Put a correct PATH into all your shell scripts and export PATH
If you don't set the PATH at the start of your script, the script will inherit the PATH from the person or program that executes your script. The inherited PATH may or may not contain the correct directories needed to find the commands used by your script - your script may fail.
Choose PATH in your script to include the system directories that contain the commands your script needs. Directories /bin and /usr/bin are almost always necessary. System scripts may need /sbin and /usr/sbin. GUI programs will need the X11 directories. Choose appropriately for the script.