If you're running into the error zsh: command not found
, this guide is for you.
This document was last updated on 13 SEPTEMBER 2023
An executable file “causes a computer to perform indicated tasks according to encoded instructions.” When you run a command in your terminal, you’re invoking an executable file.
PATH
is an environment variable.
It is a list of directories, separated by colons. The directories in that list contain executables.
When you run a command in your terminal, your shell looks for the executable in the directories listed in your PATH
. If it can’t find the executable in any of those directories, the command will fail.
To see the value of your PATH
, run echo $PATH
. The output should look something like this:
/Users/alyhursh/.nvm/versions/node/v8.17.0/bin:/Users/alyhursh/.toolbox/bin/:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/Users/alyhursh/.fzf/bin
Since looking at a colon-separated list is hard, here’s the same information with each element on a new line:
/Users/alyhursh/.nvm/versions/node/v8.17.0/bin
/Users/alyhursh/.toolbox/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/go/bin
/Users/alyhursh/.fzf/bin
Those are the directories my shell will search for my executables.
You can get your terminal to display the elements of your path on new lines with:
echo "${PATH//:/$'\n'}"
Run which git
The output is likely usr/bin/git
— that’s where the git executable is located.
See how usr/bin
is on my PATH
? Remember that usr/bin/git
is where my git executable is located? This is how my shell finds git.
Your PATH
is defined in your shell files. You will likely find references to PATH
in a file called ~/.zshrc
. To display the contents of that file in your terminal, run cat ~/.zshrc
.
In my ~/.zshrc
file, I see a reference that looks like this:
export PATH=~/.toolbox/bin/:$PATH
What this says in English is “update my PATH
environment variable to include ~/.toolbox/bin/
plus whatever my PATH
was before.”
If I wanted to add another directory to my path, I could add another line, like this:
export PATH=~/.another/directory/for/my/path:$PATH
Or, I could do it by updating the original line:
export PATH=~/.toolbox/bin:~/.another/directory/for/my/path:$PATH
Remember to separate directories with a :
When you make changes to shell configuration files, you need them to be executed. To make those changes take effect you could close your terminal and reopen it, or you can “source” the file that has the changes. To “source” the file, run source ~/.zshrc
(or whatever file you need to source).
If you add a directory to your PATH
and then you try to run an executable in that directory and it still doesn’t work, you likely forgot to source
.
If you run a command and the output looks like zsh: command not found ‹command name›
it’s almost certain that your PATH is to blame.
When you’re running a command, you’re trying to execute an executable. Where is the executable located on your computer? Is that directory on your PATH
? Run echo $PATH
to check. If the directory containing the executable isn’t on your PATH
, you’ll need to update your PATH
.
If somehow you have two executables with the same name, your shell will stop looking when it finds the first one. This isn’t particularly common, but it does happen. For instance, a while ago at Amazon we went through a brazil
cli migration. It was possible to have two versions of the brazil
cli at once. Let’s say that your two versions were in directories like this:
/path/to/version/*one*/usr/bin/brazil
/path/to/version/*two*/usr/bin/brazil
If your PATH
had them in that order, then running brazil
would only ever find version one. Even though version two is on your PATH
, it would never be executed. If you have an issue where the command you want seems to exist but isn’t behaving as expected, this might be the root of the problem.
In this case, running which -a brazil
would show both directories. Running echo $PATH
would show you what order the directories are in. Changing the order would get you the other executable!
While we’re talking about environment variables, here are a few others:
HOST
USER
SHELL
Try running echo $HOST
— What is the output?