PATH

On this page 7

PATH is the environment variable that tells a Unix or Linux shell which directories to search, and in which order, when a command is typed without a slash in its name. It holds a colon-separated list of absolute directories, such as /usr/local/bin:/usr/bin:/bin, and the first directory containing an executable file with the requested name wins.

In the Shell & terminal context, PATH is one of the most consequential pieces of session state: it decides whether python means the system interpreter or a virtual environment, whether a locally built tool shadows a packaged one, and whether a script run from cron finds its commands at all.

How the shell resolves a command through PATH

When a user types a command, the shell first checks whether the name is an alias, a shell function or a builtin such as cd or echo. Only if none of these match does it consult PATH, scanning the directories from left to right and executing the first matching file with execute permission. If no directory contains the name, the shell reports command not found, usually with exit status 127.

Bash and Zsh speed this up with a hash table of resolved locations, so the search runs once per command name. After a program is installed or moved, the cached entry can point to a stale location; hash -r in Bash or rehash in Zsh clears it. A name containing a slash, such as ./build.sh or /usr/bin/env, bypasses PATH entirely.

The table below lists the lookup order used by Bash for a simple command name.

StepWhat is checkedExample
1. AliasDefined text substitutionsalias ll=’ls -l’
2. FunctionShell functions in the sessionmkcd() { … }
3. BuiltinCommands built into the shellcd, export, type
4. Hash tablePreviously resolved pathsShown by the hash builtin
5. PATH searchDirectories from left to right/usr/local/bin before /usr/bin
Command lookup order in Bash

Typical PATH contents and where they come from

A Linux PATH is assembled from several configuration layers that run at login and when an interactive shell starts. System-wide defaults come from files such as /etc/environment, /etc/profile and scripts in /etc/profile.d, while user additions usually live in ~/.profile, ~/.bashrc or ~/.zshrc.

The common directories have stable conventions derived from the Filesystem Hierarchy Standard.

DirectoryTypical contentsManaged by
/usr/local/binLocally compiled or manually installed toolsAdministrator
/usr/binPrograms from distribution packagesPackage manager
/binEssential commands, often a link to /usr/binPackage manager
/usr/sbinSystem administration programsPackage manager
~/.local/binPer-user tools, for example from pip or pipxUser
/snap/binSnap package launchers on some systemssnapd
Common PATH directories on Linux

Most modern distributions have completed the usr merge, so /bin and /sbin are symbolic links into /usr. On those systems duplicate entries in PATH are harmless but add noise when troubleshooting.

Modifying PATH correctly

PATH is changed by reassigning the variable and exporting it, typically by prepending or appending one directory while keeping the existing value. Prepending gives the new directory priority over system commands, while appending makes it a fallback.

MethodScopePersistence
export PATH=”$HOME/bin:$PATH”Current shell and its childrenUntil the shell exits
Line in ~/.bashrc or ~/.zshrcNew interactive shells of one userPermanent for that user
Line in ~/.profileLogin sessions, including graphical onesPermanent for that user
Script in /etc/profile.dLogin shells of all usersPermanent, system-wide
Environment= in a systemd unitOne service onlyPermanent for that unit
Ways to change PATH and their scope

Tools such as Python virtual environments, version managers and language toolchains work largely by prepending their own bin directory to PATH. Activating a virtual environment, for example, places its bin directory first so that python and pip resolve to the isolated interpreter.

To inspect the result, echo "$PATH" prints the list, type -a name shows every match in priority order, and command -v name returns the path that will actually run, which is the portable choice in scripts.

PATH is only one of several search-path variables with the same colon-separated format, and confusing them is a common source of errors. Each one controls a different kind of lookup.

VariableWhat it searches forUsed by
PATHExecutable commandsShells and exec functions
LD_LIBRARY_PATHShared librariesDynamic linker
MANPATHManual pagesman
PYTHONPATHPython modulesPython interpreter
CDPATHBase directories for cdBash and Zsh
Search-path variables on Linux

Security risks and common PATH mistakes

Because PATH decides which program runs, it is a security boundary. An attacker who can write to a directory listed early in PATH can plant a malicious program named like a common command and wait for a privileged user to run it.

  • Including the current directory as . or an empty entry, such as a leading colon, lets files in any directory shadow real commands.
  • World-writable directories in PATH, such as /tmp, allow command hijacking by other users.
  • Overwriting instead of extending, as in PATH=/opt/tool/bin, removes all system commands from the session.
  • Assuming an interactive PATH in cron, where the default is often only /usr/bin:/bin, makes scheduled scripts fail.
  • Relying on user PATH under sudo is unreliable, because sudo commonly applies a fixed secure_path from the sudoers file.

Robust scripts therefore either set PATH explicitly at the top or call critical programs by absolute path, and administrators audit PATH entries for ownership and permissions.

Put simply

PATH is a list of folders the computer checks when someone types the name of a program. It works like a list of shops to visit in a fixed order. The computer goes to the first shop. If the item is not there, it tries the next one.

As soon as it finds a program with the right name, it stops looking. That is why the order of the folders matters. Two programs can share a name, and only the one in the earlier folder is used.

In practice

A data engineer installs a newer version of a command-line tool into ~/.local/bin, but typing the tool name still starts the old packaged version from /usr/bin. Running type -a shows both copies and reveals that ~/.local/bin is appended at the end of PATH in her shell configuration.

She changes the line in ~/.profile to prepend the directory, logs out and back in, and the new version runs. Later, a nightly cron job fails with command not found, because cron does not read her profile. She fixes it by setting PATH explicitly in the crontab, and the job runs reliably from then on.