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 MISTAKE / WARNING**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 THIS**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.