1. Your PATH variable is missing the directory that holds the command
This is the big one. I can't count how many times a client's script broke because someone installed a tool into /usr/local/bin but the PATH didn't include it. The shell looks for commands by scanning through a list of directories stored in the PATH environment variable. If the directory that contains the command isn't in that list, you get the dreaded bash: command not found even though the binary exists.
First, check what's in your PATH:
echo $PATH
Typical output looks like:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
If the command is in a directory like /opt/myapp/bin or ~/bin, add it. You can do this temporarily for a session:
export PATH="/opt/myapp/bin:$PATH"
That works for the current terminal. To make it permanent, add the line to your ~/.bashrc (or ~/.bash_profile if you're on macOS). Then reload with:
source ~/.bashrc
Had a client last month whose deployment script failed because they installed Docker to /usr/local/bin but the cron job ran with a minimal PATH that didn't include it. The fix was to set a full PATH inside the script itself. Always do that if your scripts run from cron or systemd.
To see where a command actually lives, use which or type -a (if it's not found, you'll get nothing). For example:
which htop
If that returns nothing, the command isn't in any PATH directory. But that doesn't mean it's not installed—could be in a non-standard location.
2. The command isn't installed at all
Second most common: you're trying to use a tool that's not on the system. I've seen this happen on fresh Ubuntu servers all the time—people expect ifconfig and it's not there by default anymore (replaced by ip). Or they try nano and it's not installed.
Check if it's a package you can install. On Debian/Ubuntu:
sudo apt update
sudo apt install <package-name>
On RHEL/CentOS/Fedora:
sudo yum install <package-name> # older
sudo dnf install <package-name> # newer
If you don't know the package name, search for it. For example, if you get htop: command not found, do:
apt search htop
That'll show the package to install. Same goes for curl, git, vim, etc. A lot of minimal installs don't include these by default.
One time I was setting up a monitoring script on a client's CentOS box and it failed because wget wasn't installed. The previous sysadmin had never used it. Two minutes with yum install wget and it was done.
3. You're making a typo (and the command doesn't exist)
Sounds stupid, but it's more common than you'd think. The command might exist under a slightly different name, or you missed a character. For example, sudo apt update vs sudo apt update—missing that final 'e' in update gives you nothing.
Check the spelling. Is it git status or git status? Wait, both are right. But git staus won't work. Also, be careful with case sensitivity—Linux commands are case-sensitive. LS is not ls.
If you're not sure, use tab completion. Type the first few letters and press Tab. Bash will autocomplete or show you what's available. For instance:
sys
Shows systemctl, sysctl, systemd-analyze, etc. This cuts down typos massively.
Also, check if you accidentally included a space before the command. A leading space is fine in interactive shells, but in scripts it can break. And check for invisible characters if you copied a command from a website—sometimes they include a non-breaking space that looks like a space but isn't.
4. The command is a shell builtin and you're using a different shell
This one catches people who switch from bash to zsh or sh. Some commands like export, alias, cd are built into the shell. But if you're in a restricted shell or a script that uses #!/bin/sh, you might not have access to everything you expect.
For example, source is a bash builtin, but in sh it might not exist (use . instead). Or echo behaves differently on some systems.
Check your current shell:
echo $SHELL
If you're in sh and need bash features, run bash or change the shebang line in your script.
5. Permissions are blocking execution
Less common, but I've seen it. The command might exist and be in PATH, but the file isn't executable. You'll get a Permission denied error usually, but sometimes that's masked as command not found if the shell can't even list it.
Check with:
ls -l /path/to/command
If the execute bits are missing, add them:
chmod +x /path/to/command
If you're dealing with a script you wrote, make sure it has a proper shebang (like #!/bin/bash) and is executable.
Quick-reference table
| Cause | How to diagnose | Fix |
|---|---|---|
| PATH missing directory | echo $PATH and check if command's dir is there |
Add directory to PATH via export or .bashrc |
| Command not installed | which <command> returns nothing |
Install package via apt/yum/dnf |
| Typo or wrong name | Tab completion shows alternatives | Check spelling and case; use full name |
| Wrong shell or builtin | echo $SHELL |
Switch to bash or use appropriate syntax |
| Permissions too strict | ls -l shows no 'x' bits |
chmod +x on the file |
That covers the main reasons. Most of the time it's the PATH thing. Keep your PATH clean and your commands installed, and you'll rarely see this error again.