Linux Error Guide: 'bash: somecmd: command not found' — Fix your PATH or install the package
Understand why bash cannot find a command, from missing packages and PATH gaps to stale hash caches and login-shell rc files, with concrete diagnostic steps.
- #linux
- #troubleshooting
- #errors
- #bash
Stuck on this Linux Admins error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
You type a command, press enter, and bash tells you it does not exist:
bash: somecmd: command not found
This is one of the most common errors on any Linux system, and it is broader than “you need to install something.” What bash is really saying is that after searching every directory listed in your $PATH environment variable, it found no executable file named somecmd, and no shell alias or function by that name either. The binary might genuinely be absent, or it might be installed in a directory that is not on your PATH, or you may have a typo, or bash may be caching a stale location from before you moved the file.
Because the shell reports the same message for all of these causes, the fix depends entirely on which one you are hitting. This guide separates them cleanly and gives you a short set of commands that will tell you, in under a minute, whether to install a package, edit a startup file, or simply refresh the shell’s lookup cache.
Symptoms
- Running
somecmdyieldsbash: somecmd: command not found. - The same command works for
root(or undersudo) but not for a regular user, or vice versa. - The command works in an interactive terminal but fails inside a cron job, a systemd
ExecStart, or a non-interactive script. - The command worked yesterday and stopped after a package upgrade, a reinstall, or moving the binary.
sudo somecmdreportscommand not foundeven though the binary clearly exists in/usr/sbin.
Common Root Causes
-
The package is not installed. The most straightforward case: nothing on the system provides
somecmd. -
The command is not on
$PATH. The binary exists, but its directory is not in the colon-separatedPATHthe shell searches. -
sbindirectories missing from a non-root PATH. System administration tools live in/usr/sbinand/sbin. Some distributions only add these to root’sPATH, so a normal user callingip,ss, oriptablesby bare name gets “command not found.” -
A typo.
grpeforgrep, or a copied command with a non-breaking space embedded in it. -
Stale shell hash cache. bash caches the full path of commands it has run. If you move or reinstall a binary to a different directory during the same session, bash may keep looking at the old location.
-
Custom install directory not exported. Tools installed to
/usr/local/bin,~/.local/bin, or a language-specific bin (npm global, pip user, cargo) require that directory to be added toPATHin a startup file that actually gets sourced. -
Alias or function defined only for interactive shells. If
somecmdis really a shell alias or function defined in~/.bashrc, it will not exist in non-interactive shells (scripts, cron, systemd), which do not read~/.bashrc.
Diagnostic Workflow
First, ask the shell to resolve the name. type is the most informative because it reports aliases, functions, builtins, and PATH hits all at once:
type somecmd
command -v somecmd
which somecmd
If all three fail, the command is not reachable. If type says it is an alias or function, then the definition simply is not present in the current shell.
Inspect your PATH and confirm whether the binary lives in a directory that is (or is not) on it:
echo "$PATH"
ls -l /usr/bin/somecmd /usr/local/bin/somecmd 2>/dev/null
If you find the file in, say, /usr/local/bin but that directory is absent from echo "$PATH", you have a PATH problem, not a missing package.
If the binary is nowhere on disk, find out which package provides it. The command differs by distribution:
# Debian / Ubuntu (install apt-file first, then update its cache)
sudo apt-get install apt-file
sudo apt-file update
apt-file search bin/somecmd
# Fedora / RHEL 8+ / other dnf systems
dnf provides '*/somecmd'
# Older RHEL / CentOS with yum
yum whatprovides '*/somecmd'
If you recently moved or reinstalled the binary and the shell still cannot find it even though PATH is correct, clear bash’s cached lookups:
hash -r
Finally, if the problem only appears in scripts or services, determine which startup file defines your PATH. Login shells read ~/.bash_profile or ~/.profile; interactive non-login shells read ~/.bashrc; non-interactive shells read neither by default:
# Is this a login shell? Compare interactive vs non-interactive behavior
grep -n 'PATH' ~/.bashrc ~/.profile ~/.bash_profile 2>/dev/null
Example Root Cause Analysis
A developer installed a linter with pip install --user ruff and then ran ruff check ., only to get bash: ruff: command not found. They started diagnosing:
command -v ruff
# (no output, exit status 1)
ls -l ~/.local/bin/ruff
# -rwxr-xr-x 1 dev dev 214 Jul 7 10:02 /home/dev/.local/bin/ruff
The binary exists in ~/.local/bin. The next check reveals why the shell cannot see it:
echo "$PATH"
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
~/.local/bin is not on the PATH. The pip --user install placed the executable exactly where it should, but nothing exports that directory. The fix is to add it to the correct startup file and reload:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
command -v ruff
# /home/dev/.local/bin/ruff
Had this same command been needed inside a cron job, editing ~/.bashrc would not have been enough, because cron does not source it. In that case the fix is to set an explicit PATH in the crontab or call the tool by absolute path, /home/dev/.local/bin/ruff.
Prevention Best Practices
- Install user tools into a standard bin and export it once. Add
~/.local/bintoPATHin your shell startup so pip, npm, cargo, and go installs are found automatically. - Put PATH edits in the file that is actually sourced. For most interactive setups that is
~/.bashrc; for login-only environments use~/.profile. Sourcing one from the other keeps behavior consistent. - Never assume
sbinis on PATH for non-root users. In scripts that run administrative tools, reference them by absolute path (/usr/sbin/ss) or set an explicit PATH at the top. - Set an explicit PATH in cron and systemd units. Non-interactive contexts start with a minimal PATH; declare it rather than relying on inherited environment.
- Run
hash -rafter moving binaries. It costs nothing and avoids a confusing stale-cache failure within a long-lived session. - Prefer absolute paths in automation. Scripts that must be robust across machines should not depend on a particular PATH being present.
Quick Command Reference
# What does the shell resolve the name to?
type somecmd
command -v somecmd
which somecmd
# Inspect PATH and check likely locations
echo "$PATH"
ls -l /usr/bin/somecmd /usr/local/bin/somecmd ~/.local/bin/somecmd 2>/dev/null
# Which package provides the command?
apt-file search bin/somecmd # Debian/Ubuntu
dnf provides '*/somecmd' # Fedora/RHEL 8+
yum whatprovides '*/somecmd' # older RHEL/CentOS
# Clear the shell's cached command locations
hash -r
# Add a custom bin dir to PATH (interactive shells)
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# Bypass PATH entirely when you must
/usr/local/bin/somecmd
Conclusion
command not found is bash reporting a failed search, not necessarily a missing program. Resolve it in order: use type and command -v to see whether the shell knows the name, inspect $PATH and the on-disk location to decide between a missing package and a PATH gap, query your package manager if the binary truly is absent, and run hash -r if you moved something mid-session. When the failure only appears in scripts, cron, or systemd, remember that non-interactive shells do not read ~/.bashrc, so PATH and aliases must be set explicitly. With those few checks you can reliably tell whether the answer is to install, to fix a startup file, or simply to refresh the shell.
Fixed it? Get 500 Linux Admins & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.