Linux PATH Environment Variable: View, Use, and Modify Command Search Paths
Learn how Linux PATH works, how shells locate commands and scripts, how to inspect command resolution, and how to safely modify PATH temporarily or permanently.
The Linux PATH environment variable tells a shell where to look for commands. Understanding PATH explains why a command works from one directory but not another, why one version of a program runs instead of another, and how to make your own scripts available by name.
This lesson assumes familiarity with shell commands, filesystem navigation, working directories, basic permissions, and simple shell scripts. For background, see File Structure in Linux and Bourne Again Shell Bash.
What PATH means
An environment variable is a named value made available to a shell and, when exported, to programs that the shell starts. PATH is a special environment variable containing an ordered list of directories.
When you enter a command by its bare name, without a slash, the shell searches the directories in PATH from left to right. For example, when you enter date, the shell may look for an executable named date in directories such as /usr/local/bin, /usr/bin, and /bin.
PATH affects command lookup; it does not identify your current working directory. The current working directory is the directory in which the shell is presently operating. It is not automatically searched for commands.
PATH format and search order
Linux PATH uses a colon-separated list. Each item is a directory, and the shell checks those directories in left-to-right order.
/usr/local/bin:/usr/bin:/bin:/home/user/.local/bin
In this example, /usr/local/bin is searched first. If it does not contain a suitable executable, the shell checks /usr/bin, then /bin, and so on.
Directory order matters when two directories contain programs with the same name. The first matching executable normally wins. For example, if both /usr/local/bin/tool and /usr/bin/tool are executable, placing /usr/local/bin first causes the local version to be selected.
Empty PATH entries and the dot entry
A dot entry, written as ., explicitly means the current working directory. An empty entry can also represent the current directory in PATH syntax. Empty entries can occur accidentally, for example in a value containing two adjacent colons such as /usr/bin::/bin, or at the beginning or end of the value.
Searching the current directory automatically can be risky. A malicious or accidentally named executable in the current directory could run when you expect a trusted system command. This risk is especially serious when using elevated privileges. Prefer explicit forms such as ./program when you intentionally want to run a file from the current directory.
Viewing PATH
Use shell variable expansion to print the complete value:
echo "$PATH"
Because a normal PATH is one long line, printing one directory per line can make it easier to inspect:
printf '%s\n' "$PATH" | tr ':' '\n'
These commands display the PATH value. They do not list the files inside each directory. To inspect directory contents, use a separate command such as ls on a particular directory, while remembering that PATH may contain directories that do not currently exist.
How the shell resolves a command
When you enter a command, the shell first determines what kind of command name it is. A name may refer to an alias, a shell function, a shell builtin, or an external executable file.
- An alias is a shell-defined substitution, such as an alias that adds options to a common command.
- A shell function is a group of shell commands defined inside the current shell.
- A shell builtin is implemented by the shell itself. Examples include commands such as
cdandexport. - An external command is normally an executable file found by searching PATH.
The exact precedence can vary slightly between shells, but aliases, functions, and builtins can take precedence over an external file with the same name. Once the shell performs a PATH search for a bare command name, it checks directories in sequence and normally uses the first matching executable.
A command containing a slash is treated as a pathname, not as a bare command name. The shell does not search PATH for ./script.sh or /usr/local/bin/script.sh.
Checking what will run
command -v asks the current shell what it would use for a command name:
command -v command_name
command -v ls
The type command provides more detail about aliases, functions, builtins, and external commands:
type command_name
type cd
type ls
which is sometimes used for this purpose, but it commonly searches only external executables and may not reveal an alias, function, or builtin. For shell-aware diagnostics, prefer command -v and type.
Running scripts and programs
Suppose script.sh is stored in /home/user/bin, and that directory is included in PATH. From another working directory, you can run the script by name:
script.sh
The shell searches PATH, finds /home/user/bin/script.sh, and attempts to execute it. If the script is in your current directory but that directory is not in PATH, entering only its filename normally fails:
script.sh
# bash: script.sh: command not found
Use a relative pathname to explicitly select the current directory:
./script.sh
A relative path is interpreted from the current working directory. You can also use an absolute path, which is a complete filesystem location beginning with /:
/home/user/script.sh
| Invocation form | Example | Uses PATH search | When to use |
|---|---|---|---|
| Bare name | script.sh | Yes | The program is in a PATH directory and you want to run it by name. |
| Relative pathname | ./script.sh | No | The file is relative to the current working directory. |
| Absolute pathname | /home/user/script.sh | No | You need to identify the exact file regardless of the current directory or PATH. |
Executable permission and shebangs
To run a script directly as script.sh or ./script.sh, the file needs executable permission:
chmod +x script.sh
Inspect its permissions with:
ls -l script.sh
A directly executable script should normally begin with a shebang, which is the first line identifying its interpreter. For example:
#!/bin/sh
Without a valid shebang, or when the named interpreter is unavailable, the script can be found but fail with an interpreter-related error. You can sometimes invoke the interpreter explicitly, for example with sh script.sh, but that may behave differently from direct execution if the script expects another interpreter.
Changing PATH temporarily
To prepend a directory for the current shell session, use:
export PATH="$HOME/.local/bin:$PATH"
Prepending gives the new directory higher precedence than existing directories. This is useful when you want your personal version of a command to be selected before a system version.
To append a directory instead, use:
export PATH="$PATH:$HOME/.local/bin"
Appending gives existing directories priority. It is often safer when you want system commands to win if names conflict.
The $PATH portion preserves the old value. Replacing it accidentally can make standard commands unavailable:
# Risky: discards the existing PATH
export PATH="$HOME/.local/bin"
export marks the shell variable for inheritance by child processes. Programs and scripts launched after the assignment receive the updated PATH. The change normally affects only the current shell and its descendants; closing that shell removes the temporary change.
Changing PATH persistently
To make a PATH change apply to future sessions, put an export command in the startup file used by your shell. Common files include:
~/.bashrcfor many interactive Bash shells.~/.bash_profilefor Bash login shells. It may load~/.bashrc, depending on its contents.~/.profilefor login-session settings on many systems.~/.zshrcfor interactive Zsh shells.
The correct file depends on the active shell and whether the session is interactive, a login shell, or both. Check the shell you are using before editing a startup file:
echo "$SHELL"
A common personal executable directory is ~/.local/bin. Create it if necessary:
mkdir -p "$HOME/.local/bin"
For Bash interactive shells, add this line to ~/.bashrc:
export PATH="$HOME/.local/bin:$PATH"
Then reload the file:
source ~/.bashrc
For Zsh, add the same export to ~/.zshrc and reload it:
source ~/.zshrc
Alternatively, open a new terminal or start a new login session. If a new session does not contain the change, the command may have been placed in the wrong startup file or may not use export.
| Method | Example location or command | Duration | Typical use |
|---|---|---|---|
| Shell assignment | export PATH="...:$PATH" | Current shell and its children | Testing a change or using a tool temporarily. |
| Bash startup file | ~/.bashrc or ~/.bash_profile | Future applicable Bash sessions | Persistent Bash configuration. |
| Profile startup file | ~/.profile | Future login sessions | Environment settings shared by login-session programs. |
| Zsh startup file | ~/.zshrc | Future interactive Zsh sessions | Persistent Zsh configuration. |
Verifying and diagnosing PATH problems
| Tool | What it reports | Caveats |
|---|---|---|
command -v name | The command selected by the current shell, including a path or shell-defined command where supported. | Output format varies by shell. |
type name | Whether the name is an alias, function, builtin, or external command. | It is a shell builtin or shell-specific diagnostic. |
which name | Often the path to an external executable. | It commonly ignores aliases, functions, and builtins, so it is less reliable for complete command resolution. |
ls -l file | File type and permission bits, including executable permission. | It does not determine which PATH entry the shell will select. |
If a command is not found, first check the PATH value and then check resolution:
printf '%s\n' "$PATH" | tr ':' '\n'
command -v command_name
type command_name
If a file exists but ./script.sh returns permission denied, inspect it:
ls -l ./script.sh
chmod +x ./script.sh
If the file has execute permission but still fails, check its shebang and confirm that the referenced interpreter exists. Filesystems mounted with execution restrictions can also prevent execution even when the permission bits look correct.
Common symptoms and fixes
- Filename alone returns command not found: The current directory is probably not in PATH. Use
./script.sh, an absolute pathname, or install the script in an appropriate PATH directory. - The wrong command version runs: Another executable may appear earlier in PATH, or an alias or function may override it. Use
typeandcommand -v, then adjust ordering or use an absolute pathname. - Standard commands stopped working after editing PATH: The old value was probably overwritten. Restore appropriate system directories and include the existing value with
$PATHin future assignments. - A new terminal does not recognize the added directory: Confirm the active shell, choose its relevant startup file, use an exported assignment, and reload the file or open a new session.
Safe PATH practices
- Do not put writable or untrusted directories early in PATH, especially when running commands with elevated privileges.
- Do not assume the current directory is searched automatically. Use
./namewhen you intentionally want the local file. - Keep personal scripts in a user-controlled directory such as
~/.local/bininstead of installing them into system directories such as/binor/usr/bin. - Use an explicit absolute pathname when certainty about the executable matters, such as in administrative scripts or security-sensitive operations.
- Preserve the existing PATH when adding entries, and avoid adding the same directory repeatedly in startup files.
Practical example: a personal script directory
Create a user-owned directory, place an executable script in it, and add it to PATH for the current shell:
mkdir -p "$HOME/.local/bin"
export PATH="$HOME/.local/bin:$PATH"
After putting an executable file named hello in that directory, verify the selected file:
command -v hello
If the result is /home/user/.local/bin/hello, the shell can run it from any working directory by entering:
hello
If another PATH directory also contains a program named hello, the directory placed first determines which one runs. Use type hello and command -v hello to investigate, or run the desired file with its absolute pathname.
Key points
- PATH is an inherited environment variable containing an ordered, colon-separated list of directories.
- A bare command name causes the shell to search PATH from left to right; the first suitable executable normally wins.
- A command containing a slash uses the specified relative or absolute pathname and does not require a PATH search.
- The current working directory is not automatically part of command lookup.
- Use
export PATH="new-directory:$PATH"orexport PATH="$PATH:new-directory"to preserve the existing value. - Use
command -v,type, andls -lto diagnose resolution and permission problems. - For persistent personal commands, use a directory such as
~/.local/binand configure the startup file appropriate for your shell.
For a related way to inspect the exact executable selected for a command, see Show The Full Path Of Shell Commands.