The Command Path — How the Shell Finds Programs
When Asha types ls, she never says where the ls program is. The shell finds it anyway. Later she writes her own script, harvest-report, types its name, and gets command not found even though the file is right there in front of her. Both of these come down to one variable.
The rule
The shell searches PATH left to right; the first match wins.
PATH is a list of directories separated by colons:
$ echo $PATH
/home/asha/bin:/usr/local/bin:/usr/bin:/binWhen you type a command name without a slash, the shell checks each directory in that list in order, and runs the first file with that name that it's allowed to execute. If no directory has one, you see command not found.
The shell does not look in the current directory unless it's on the list, and for safety it normally isn't. That's why a script sitting right next to you has to be run with a path:
$ ./harvest-report # a path with a slash: skip the search
$ ~/garden/harvest-report # also a pathTo ask the shell what a name will run:
$ type ls
ls is aliased to `ls --color=auto'
$ command -v python3
/usr/bin/python3
$ which python3
/usr/bin/python3type is the most honest of the three because it also knows about aliases, functions and builtins (commands such as cd that live inside the shell itself). The shell checks those before it searches PATH at all.
To make her own scripts runnable from anywhere, Asha puts them in ~/bin and adds that folder to the front of her PATH:
export PATH="$HOME/bin:$PATH"The shortcut
For any command, look for a slash. With a slash, it's a path and the shell runs exactly that file. Without one, walk the PATH list from left to right, and the first directory that has the name is the one you get.
The list
PATHis/home/asha/bin:/usr/local/bin:/usr/bin.
A classic trap: someone writes PATH=~/bin and forgets :$PATH. Every other directory has now been dropped from the list, so even ls stops working until they fix the variable or open a new shell.
Drills
Answer fast — trust the rule.
What separates the directories in PATH?
harvest-report is in the current directory and is executable, but typing harvest-report says "command not found". Why?
python3 exists in /usr/local/bin and /usr/bin, and PATH is /usr/bin:/usr/local/bin. Which one runs?
Which line adds ~/bin to the front of PATH without losing the rest?
Remember
- The shell searches PATH left to right, and the first match wins.
- Look for a slash: a name with a slash is a path that runs directly, and a name without one is searched for in PATH.
- Use
typeto see what a name really runs, and never overwrite PATH without keeping:$PATH.
