Command Not Found After Installing Package on Linux
You installed a package but the command doesn't run. Here's why — your shell isn't looking in the right place, or the install didn't put the binary where you expect.
So you ran sudo apt install some-tool or cargo install thingy or npm install -g package, and you're sure it worked — no errors, green checkmarks. But then you type thingy --version and your shell spits back command not found: thingy. What's actually happening here is your shell doesn't know where the binary lives. The package is on disk, but $PATH doesn't include that directory. Or the install never put a binary there at all. Let's walk through the three most common reasons, starting with the one that trips up 80% of people.
1. The Binary Isn't in Your Shell's PATH
This is the fix I reach for first, because it's the most common. After you install a package, the binary gets placed in a directory like /usr/local/bin, ~/.local/bin, or ~/.cargo/bin. Your shell only searches the directories listed in $PATH. If that directory isn't there, the command won't be found no matter how many times you install the package.
The quickest test: run which thingy or type thingy. Both return nothing or not found. Then check where the binary actually is: find /usr -name 'thingy' -type f 2>/dev/null. If it shows up in /usr/local/bin but your $PATH doesn't contain that directory, that's your problem.
How to fix it: Add the directory to your PATH in your shell's config file. For bash, that's ~/.bashrc:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
For zsh, it's ~/.zshrc — same idea, different file. For fish, use set -U fish_user_paths $HOME/.local/bin $fish_user_paths and restart the shell.
The reason sourcing works immediately is because source re-reads the config file and updates the current shell session. Without it, the new PATH only applies to new terminal windows. I've seen people reboot their whole machine over this. Don't be that person.
Real-world example: on Ubuntu 22.04, installing hugo via sudo apt install hugo puts it in /usr/bin, which is already in PATH. No issue. But if you install the extended version from GitHub releases and extract the binary to ~/bin (which doesn't exist by default), your shell won't see it until you add ~/bin to PATH.
2. The Package Installs to a Non-Standard Location (Snap, Flatpak, Brew)
Not all package managers put binaries in the same place. Snap is a classic offender. On Ubuntu, sudo snap install hello-world installs to /snap/bin/hello-world. But /snap/bin might not be in your PATH if you're on a fresh install or a non-Ubuntu distro. Same with Homebrew on Linux: it installs to /home/linuxbrew/.linuxbrew/bin, not /usr/bin.
How to check: Run snap list to confirm the package is installed. Then ls -la /snap/bin/ to see the binary. If it's there but which hello-world returns nothing, add /snap/bin to your PATH as above.
For Flatpak, the binary wrapper is usually in /var/lib/flatpak/exports/bin or ~/.local/share/flatpak/exports/bin. The command won't be flatpak run — it's a wrapper script. Same fix: add the directory to PATH.
Homebrew on Linux is a bit trickier because it also needs HOMEBREW_PREFIX set. Run brew doctor to see if it complains about PATH. It usually tells you exactly what to add. Follow that.
Why this happens: Package managers like Snap and Flatpak sandbox applications. They don't assume you want the binary in /usr/bin because that directory is typically reserved for system packages managed by apt or dnf. They use separate directories to avoid collisions and permission issues. It's a design choice that works well once you know the convention.
3. The Install Succeeded But No Binary Was Placed in PATH (Cargo, npm, pip)
This one is subtle. You run cargo install ripgrep and it compiles and finishes with zero errors. But rg returns command not found. What's actually happening here is Cargo installed the binary to ~/.cargo/bin, but that directory isn't in your PATH by default on many systems.
The fix: add ~/.cargo/bin to PATH. Same approach as cause #1. But there's a twist — some installers (like npm install -g) require root permission or a specific npm prefix. If you used sudo npm install -g, the global binaries go to /usr/local/lib/node_modules/.bin/, not /usr/local/bin. Check with npm root -g or npm bin -g.
For pip: pip install --user saves to ~/.local/bin on Linux. That's not in PATH on many distros. Check with python3 -m site --user-base, then append /bin to that path. Fedora, for example, does not add ~/.local/bin by default. Ubuntu does for interactive shells but not for scripts or cron jobs — another gotcha.
Specific real-world trigger: I hit this on a fresh Fedora 39 install. Installed pip install --user poetry. No errors. Typed poetry --version. Nothing. Checked ~/.local/bin — the binary was there. Added export PATH="$HOME/.local/bin:$PATH" to ~/.bashrc and sourced it. Worked immediately. The lesson: don't assume your distro includes ~/.local/bin.
Quick Reference Summary
| Cause | Common Package Managers | Binary Directory | Fix |
|---|---|---|---|
| Binary not in PATH | Any manual install, tarball extraction | ~/bin, /usr/local/bin, /opt/bin |
Add directory to $PATH in shell config |
| Snap/Flatpak/Brew location | snap, flatpak, brew | /snap/bin, /var/lib/flatpak/exports/bin, /home/linuxbrew/.linuxbrew/bin |
Add directory to PATH |
| Language-specific package manager | cargo, npm, pip, go install | ~/.cargo/bin, /usr/local/lib/node_modules/.bin, ~/.local/bin |
Find the bin path with which/npm bin -g/pip show -f, then add to PATH |
One last thing: if none of these work, check that the package actually installed a binary. Some packages are libraries, not tools. Run apt list --installed 2>/dev/null | grep thingy or pip list | grep thingy. If it's there but no binary, the package might be a dependency, not a standalone command. Check the docs.
Was this solution helpful?