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
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.jsPractical Commands
## View current PATHecho $PATH## /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ## Find which binary a command resolves towhich node## /usr/local/bin/node which python3## /usr/bin/python3 ## type is more thorough than whichtype -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"' >> ~/.bashrcsource ~/.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.txtcat /tmp/cron-env.txt | grep PATH## PATH=/usr/bin:/bin <- minimal! ## Fix cron PATH by setting it in the scriptexport PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binTroubleshooting
| 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 MistakeModifying PATH in
~/.bashrcand expecting it to work in cron or systemd services.~/.bashrcis only sourced for interactive bash sessions. Cron and systemd have their own minimal environments. Always set PATH explicitly in automation scripts.
RememberPATH order matters. If
/usr/local/bincomes before/usr/bin, and both have apython3, the one in/usr/local/binruns. 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.