Terminal 'command not found': Root Cause and Fix Guide
After installing a CLI tool, the terminal may still report command not found. This guide explains why the error occurs, how to locate the missing executable, and how to correctly update PATH on macOS, Linux, and Windows.
After installing a command-line tool, you happily type its name in the terminal, but instead of running it, you get an error:
- macOS/Linux (zsh):
zsh: command not found: xxx - Linux (bash):
bash: xxx: command not found - Windows (PowerShell/CMD):
'xxx' is not recognized as an internal or external command
A quick search online often gives the same advice: add a directory to PATH.
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
Do not copy this blindly. It helps some users, but for other installation methods it may do nothing or make the environment harder to manage. After following it, you may still see command not found.
The real issue is that most tutorials assume the tool was installed in a specific directory, such as a user-level bin directory. That is only one possible install location. Before changing PATH, you need to find where the executable actually is.
1. What command not found really means
The error is simple: when you run a command, the shell does not search the entire disk. It searches the directories listed in the PATH environment variable, one by one, for an executable with the same name.
- If one of those directories contains the file, the shell runs it.
- If all directories have been checked and nothing matches, the shell reports
command not found.
So the message does not necessarily mean “the tool is not installed on this machine.” It often means “the tool may be installed, but its directory is not included in PATH.” These two cases require different fixes, and mixing them is why many users take the wrong path.
2. Why adding PATH sometimes does not work
PATH is only a list of directories. Adding a directory only helps if the executable is actually inside that directory. Where the executable is installed depends on the installation method you used:
| Installation method | Typical executable location |
|---|---|
| Official native install script (download and execute) | User-level bin directory, such as ~/.local/bin |
| Third-party system-level package manager (ARM architecture) | A corresponding bin directory under /opt |
| Third-party system-level package manager (x86 architecture) | Such as /usr/local/bin |
| Global install through a language-specific package manager | A global bin directory that may change with the runtime version |
Only official native install scripts place the executable in a user-level bin directory. If you installed the tool with a third-party package manager, the executable may be somewhere else. If you then add only the user-level bin directory to PATH, you are adding a directory that does not contain the current tool. The error will remain.
The correct first step is therefore not to modify PATH, but to locate the executable.
3. Start by locating the command, not changing configuration
Regardless of your operating system or installation method, first run:
which -a xxx
which -a lists all matching executables found in the current PATH. Then handle the result based on the output.
Case 1: A path is printed
For example:
/usr/local/bin/xxx
This means the command is already in PATH and should normally work. If you still get command not found, the likely causes are multiple conflicting versions or a shell session that has not loaded the latest configuration. See the “multiple commands with the same name” section.
Case 2: Nothing is printed
PATH does not contain a matching executable. You then need to determine whether the tool is installed but missing from PATH, or not installed at all. Check common installation locations:
ls -la ~/.local/bin/xxx # Official native install scriptsls -la /usr/local/bin/xxx # Common location for system-level package managersls -la /opt/*/bin/xxx # Third-party optional software directories
You can also check whether a language package manager installed it globally:
<package-manager> -g ls <package-name>
If one of these commands prints the executable, that directory is the one you may need to add to PATH. If all of them return nothing, the command was probably not installed successfully. In that case, go back and troubleshoot the installation itself (network, permissions, install source, and so on) instead of spending time on PATH.
4. Correct fix for macOS and Linux
After confirming the real directory, you can modify PATH. The key is to add or prepend the directory, not overwrite the existing PATH:
export PATH="/your/real/directory:$PATH"
Test it temporarily in the current session:
source ~/.zshrc # or ~/.bashrc, depending on your shellwhich xxx # should print the path under the newly configured directory
Once it works, add the same line to the appropriate startup file so it persists:
- zsh:
~/.zshrc - bash:
~/.bashrcor~/.bash_profile
Common mistakes:
- Editing the wrong startup file. Different shells read different configuration files.
- Changing the file but not running
source, or not reopening the terminal, so the change is not loaded into the current session. - Using
>instead of>>when appending, which overwrites the original file and can erase your existing PATH.
5. Correct approach on Windows
Windows handles PATH differently from Unix-like systems. The value is stored in environment variables, not in shell startup scripts.
Using the graphical interface: open “System Properties → Advanced → Environment Variables”. Edit the Path entry under User variables or System variables, add a new entry pointing to the directory containing the executable, and save.
Using PowerShell to modify only the current user’s PATH:
$dir = "$env:USERPROFILE\.local\bin"[Environment]::SetEnvironmentVariable("Path",[Environment]::GetEnvironmentVariable("Path","User") + ";$dir","User")
After changing environment variables, close and reopen the terminal. Changes to environment variables do not affect already-open sessions. Then verify with:
where.exe xxx
where is the Windows equivalent of which -a. It lists matching executables found in PATH.
Editing system-level environment variables can affect many programs. Before making changes, back up the existing Path value to avoid breaking other software.
6. What to do when multiple commands with the same name exist
If which -a prints multiple lines, there are multiple executables with the same name. This can happen when, for example, you installed one copy with a package manager and another with a native install script. In that case, the shell runs the one that appears first in PATH, which may not be the one you want.
How to handle it:
- Set priority: put the directory you want to use earlier in PATH.
- Remove redundant installations: uninstall copies you no longer need to reduce ambiguity.
- Verify with absolute paths: run the full path directly to check what each version points to.
If you need to switch between multiple versions for different projects, use a dedicated version management solution instead of manually changing PATH. Manual changes are easy to break when moving between projects.
7. Verification and best practices
After fixing the issue, confirm it with a few commands:
which xxx # macOS/Linuxwhere xxx # Windowsxxx --version # Confirm the command runs and prints a version
If all three pass, the issue is resolved.
General best practices:
- Locate first, configure second. Always find where the tool is installed before deciding whether PATH needs to change.
- Add or prepend directories to PATH; do not overwrite the existing PATH.
- After editing configuration, run
sourceor reopen the terminal. - Prefer the configuration logic provided by the installer. Many modern installers can update PATH automatically, so manual changes may not be needed.
- Back up important configuration before modifying system-level settings.
Conclusion
command not found can look confusing, but the underlying issue is usually simple: the executable’s directory is not included in PATH. By developing the habit of locating the command with which -a, fixing the real path, and verifying with which plus --version, you can solve most environment configuration errors and avoid wasting time copying commands that do not match your setup.
