Skip to main content

PATH

PATH is an environment variable containing a colon-separated list of directories the shell searches when you type a command. The shell checks each directory in order and runs the first matching binary found. Commands not in any PATH directory require an absolute path.

Understanding Linux PATH

What Is PATH in Simple Terms

When you type node, the shell does not magically know where node is installed. It searches through a list of directories — the PATH — and runs the first node binary it finds. If node is in /usr/local/bin/node and /usr/local/bin is in your PATH, typing node works. If it is not in PATH, you get command not found.

This is the most common cause of scripts that work interactively but fail in cron, CI/CD, or as systemd services — different execution contexts have different PATH values.

How It Works

◈ DIAGRAM
You type: node server.js
Shell searches PATH in order:
+------------------------------------------+
| /usr/local/sbin <- check here first |
| /usr/local/bin <- node found here! | <- STOP, use this one
| /usr/sbin <- would check next |
| /usr/bin <- would check next |
| /sbin <- would check next |
| /bin <- would check next |
+------------------------------------------+
Runs: /usr/local/bin/node server.js

Practical Commands

Bash
## View current PATH
echo $PATH
## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
## Find which binary a command resolves to
which node
## /usr/local/bin/node
which python3
## /usr/bin/python3
## type is more thorough than which
type -a python
## python is /usr/bin/python
## python is /usr/local/bin/python <- multiple versions found
## Add a directory to PATH (current session only)
export PATH="/opt/mytools/bin:$PATH"
## Prepend to PATH -- your tools take priority over system tools
## Add permanently (for all sessions)
echo 'export PATH="/opt/mytools/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
## Add system-wide (for all users)
sudo tee /etc/profile.d/mytools.sh << 'EOF'
export PATH="/opt/mytools/bin:$PATH"
EOF
## Debug which PATH a cron job or service sees
## Add to crontab temporarily:
## * * * * * env > /tmp/cron-env.txt
cat /tmp/cron-env.txt | grep PATH
## PATH=/usr/bin:/bin <- minimal!
## Fix cron PATH by setting it in the script
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Troubleshooting

Symptom Command What to Check
command not found which commandname Not in PATH
Wrong version runs type -a commandname Earlier PATH entry wins
Works in terminal, fails in cron env > /tmp/cron.txt Cron has minimal PATH
Script works manually, fails in CI Check CI environment PATH CI has different PATH
Common Mistake

Modifying PATH in ~/.bashrc and expecting it to work in cron or systemd services. ~/.bashrc is only sourced for interactive bash sessions. Cron and systemd have their own minimal environments. Always set PATH explicitly in automation scripts.

Remember

PATH order matters. If /usr/local/bin comes before /usr/bin, and both have a python3, the one in /usr/local/bin runs. Prepending (/new/dir:$PATH) gives priority. Appending ($PATH:/new/dir) gives fallback.

Frequently Asked Questions

Why does command order matter in the PATH variable, and how can that cause confusing bugs?

The shell searches PATH directories left to right and executes the first match, so if two directories both contain a binary with the same name (say, a system Python at `/usr/bin` and a version manager's Python earlier in PATH), whichever comes first wins — silently. This is a common source of 'it works on my machine' bugs: two engineers with differently ordered PATHs, or a PATH modified by a tool installer, can run completely different binaries when typing the identical command.

What's a common mistake when modifying PATH in shell config files?

Repeatedly appending the same directory to PATH across multiple sourced files (`.bashrc`, `.bash_profile`, `.profile`) without checking if it's already there leads to a bloated, duplicated PATH that slows down every command lookup and makes debugging 'why is the wrong binary running' harder. It's also easy to accidentally prepend a directory containing a malicious or outdated binary ahead of trusted system directories, which is a real supply-chain risk if that directory is writable by other users.