ThynkDone
A terminal window displaying Linux command-line output, illustrating PATH environment variable configuration
Linux Basics

How To View and Update the Linux PATH Environment Variable

T
ThynkDone
May 9, 2026

Learn how to view and update the Linux PATH environment variable permanently or temporarily across bash and zsh, with verification, troubleshooting, and production gotchas.

Introduction

The Linux PATH environment variable is a colon-separated list of directories the shell searches when you run a command. Each time you enter a command name such as python3, grep, or myapp, the shell checks directories in PATH from left to right and runs the first executable match it finds.

In this tutorial, you will view PATH, change it temporarily and permanently across bash and zsh, verify changes, remove entries, and troubleshoot common failures. Examples are validated on Ubuntu 22.04, Debian 12, and Rocky Linux 9.

â„šī¸ Info

Commands in this guide are shown with expected output so you can compare your results and confirm each change is applied as intended.


Key Takeaways

  • PATH is a colon-separated list of directories the shell searches left to right when resolving a command.
  • echo $PATH and printenv PATH both display the current value.
  • export PATH=$PATH:/new/dir changes PATH for the current session only.
  • Permanent changes go in ~/.bashrc for bash, ~/.zshrc for zsh, and /etc/environment for system-wide values.
  • Order matters: directories listed earlier in PATH take precedence over later ones.

Prerequisites

  • A Linux system running bash or zsh (Ubuntu 22.04, Debian 12, or Rocky Linux 9).
  • A non-root user with sudo privileges.
  • Basic familiarity with environment variables.

Understanding How the Linux PATH Variable Works

What PATH Contains and How the Shell Uses It

PATH stores absolute directory paths separated by colons. When you run a command without a full path, your shell inspects each directory in order and executes the first matching file with execute permissions.

To inspect your PATH as one directory per line, run:

tr ':' '\n' <<< "$PATH"

If the same executable name exists in more than one directory, the first directory in this list wins.

How PATH Is Inherited by Processes and Subshells

Child processes inherit exported environment variables from the parent process. A shell variable exists only in the current shell until you mark it with export. PATH follows this same rule.

MYVAR="hello"
bash -c 'echo $MYVAR'   # prints nothing

export MYVAR="hello"
bash -c 'echo $MYVAR'   # prints: hello

Step 1 — Viewing the Current PATH Variable

Using echo to Display PATH

echo $PATH is the fastest way to see what directories your shell searches:

echo $PATH

Using printenv to Display PATH

printenv PATH reads directly from the process environment rather than through shell expansion, making it the more reliable option in scripts and non-interactive contexts:

printenv PATH

💡 Tip

Because printenv only prints exported variables, it cleanly distinguishes inherited environment variables from local shell variables — making it the safer choice inside scripts.

Reading PATH in a Script Context

Scripts invoked with bash script.sh see a different PATH than your interactive shell because they do not source ~/.bashrc. To make a script's PATH reliable, define it explicitly at the top:

#!/usr/bin/env bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
echo "Script PATH: $PATH"

Step 2 — Adding a Directory to PATH for the Current Session

export marks a variable for inheritance by child processes and updates it immediately in the current shell. To add a directory to PATH for the current session, prepend it for higher priority or append it for lower priority:

# Prepend: /opt/myapp/bin is checked before all existing directories
export PATH="/opt/myapp/bin:$PATH"

# Append: /opt/myapp/bin is checked after all existing directories
export PATH="$PATH:/opt/myapp/bin"

âš ī¸ Warning

This change applies to the current shell session only. When you close the terminal or start a new session, PATH resets to its default value. To make it permanent, see Step 3.


Step 3 — Adding a Directory to PATH Permanently

Choosing the Right Configuration File

The correct startup file depends on your shell and whether the session is login or interactive non-login. Choose the file that matches how your shell is launched:

FileScopeWhen SourcedShells
~/.bashrcPer userEvery interactive non-login bash shellbash
~/.bash_profilePer userLogin bash shellsbash
~/.profilePer userLogin shells when no ~/.bash_profile existsbash, sh, dash
~/.zshrcPer userEvery interactive zsh shellzsh
~/.zprofilePer userLogin zsh shellszsh
/etc/environmentSystem-wideRead by PAM at login; not a shell scriptAll
/etc/profileSystem-wideLogin shellsbash, sh
/etc/profile.d/*.shSystem-wideSourced by /etc/profilebash, sh

💡 Tip

For most interactive use on a desktop or server where you are the only user, ~/.bashrc (bash) or ~/.zshrc (zsh) is the correct file.

Editing ~/.bashrc for Bash Users

nano ~/.bashrc

Scroll to the bottom and append:

export PATH="$PATH:/opt/myapp/bin"

Load the change without logging out:

source ~/.bashrc

Editing /etc/environment for System-Wide Changes

🚨 Danger

Do NOT use $PATH inside /etc/environment. Variable expansion is not supported in this file. Always write the complete directory list as a literal string, or you will break PATH for all users on the system.

sudo nano /etc/environment

# Set the complete literal value:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/myapp/bin"

Changes in /etc/environment take effect after the next login, not after sourcing in the current shell.


Step 4 — Verifying That PATH Changes Are Working

Using which, type, and command -v

Three commands help you verify which binary the shell will actually run:

CommandWhat It DoesBest For
which python3Returns first PATH matchQuick single-path check
type -a python3Lists all matches including aliases and functionsDiagnosing version conflicts
command -v python3POSIX-portable single-path checkScripts and portability
which python3
# /usr/bin/python3

type -a python3
# python3 is /usr/bin/python3
# python3 is /usr/local/bin/python3

command -v python3
# /usr/bin/python3

Confirming Persistence with a New Shell

Running echo $PATH in the same session that applied export does not confirm persistence. Start a fresh shell to verify:

exec bash
echo $PATH

Step 5 — Removing or Deduplicating Entries from PATH

To remove /opt/myapp/bin from the current session:

PATH=$(echo "$PATH" | sed -e 's|/opt/myapp/bin:||g' -e 's|:/opt/myapp/bin||g')
export PATH

To prevent duplicate entries when sourcing config files multiple times, use a guard pattern:

case ":$PATH:" in
  *":/opt/myapp/bin:"*) ;;
  *) export PATH="$PATH:/opt/myapp/bin" ;;
esac

💡 Tip

Wrapping colons around both $PATH and the target directory makes the pattern match a full entry, not a substring of a longer path. This prevents false positives like /opt/myapp/bin2 matching /opt/myapp/bin.


Troubleshooting Common PATH Problems

PATH Change Not Persisting After Logout

The export command updates PATH in the current shell process only. To trace which files bash sources at login:

bash -lxv 2>&1 | head -50

Wrong Version of a Binary Being Resolved

A directory containing an older version appears earlier in PATH than the newer one. Diagnose with type -a, then fix by prepending the correct directory:

type -a python3
export PATH="/opt/myapp/bin:$PATH"

PATH Changes Not Applying to GUI Applications

â„šī¸ Info

Most desktop environments source ~/.profile and /etc/environment at login, not ~/.bashrc. A change in ~/.bashrc only affects terminal emulators that spawn interactive non-login shells. Move the export line to ~/.profile or add the directory to /etc/environment, then log out and back in.


Managing PATH in Non-Standard Environments

PATH in Shell Scripts and Cron Jobs

âš ī¸ Warning

Cron runs with a minimal default PATH (typically /usr/bin:/bin). Commands available in your interactive shell may not be found. Always set PATH explicitly at the top of your crontab.

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Run myapp every hour
0 * * * * /opt/myapp/bin/myapp >> /var/log/myapp.log 2>&1

PATH in Docker Containers and Dockerfiles

ENV PATH="/opt/myapp/bin:${PATH}"

ENV persists across all subsequent layers and into the running container, so every RUN, CMD, and ENTRYPOINT instruction sees the updated value.


Common PATH Gotchas in Production

sudo Ignores Your PATH

Running a command with sudo often fails with "command not found" even when the command works without sudo. The cause is secure_path in /etc/sudoers, which replaces PATH entirely when sudo is invoked.

🚨 Danger

Always use visudo to edit /etc/sudoers. Editing the file directly with a text editor and introducing a syntax error will lock you out of sudo on that system.

sudo grep secure_path /etc/sudoers
# Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# To fix, edit with visudo and add your directory:
sudo visudo

SSH Non-Interactive Shells Do Not Source ~/.bashrc

Running a command over SSH with ssh user@host 'mycommand' spawns a non-interactive, non-login shell that sources neither ~/.bashrc nor ~/.bash_profile. Check whether a [ -z "$PS1" ] && return guard exists near the top of your ~/.bashrc. If it does, move your export PATH line above it.

Bash Caches Binary Locations

After updating PATH, bash may still run the old binary because it caches command locations in a hash table. Clear the cache:

hash -r

Command Resolution Precedence

PATH is not the first place bash looks when you run a command. The full resolution order is:

PriorityTypeExample
1 (highest)Aliasesalias python3='python3.11'
2Shell functionsfunction myapp() { ... }
3Shell builtinscd, echo, type
4Hashed locations (binary cache)Previously run commands
5 (lowest)PATH directory scan/usr/bin/python3

💡 Tip

This is why type -a is more useful than which for diagnosing unexpected behavior. If type python3 returns 'python3 is aliased to python', the alias takes precedence over any PATH entry.

PATH in systemd Service Units

âš ī¸ Warning

When running applications as systemd services, the PATH from your user environment is not inherited. systemd starts services with a minimal environment. Set PATH explicitly in the unit file.

[Service]
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/myapp/bin"
ExecStart=/opt/myapp/bin/myapp
sudo systemctl daemon-reload
sudo systemctl restart myapp

Conclusion

This tutorial walked through the full lifecycle of PATH management on Linux: reading the current value, making temporary and permanent changes across bash and zsh, choosing the right startup file for your session type, verifying that the correct binary is resolved, removing and deduplicating entries, and diagnosing failures in production environments including sudo stripping PATH, SSH non-interactive shells, stale binary caches, and systemd service isolation.

â„šī¸ Info

Next steps: explore how to read and set other environmental and shell variables on Linux, learn about bash aliases and functions, or dive into an introduction to the Linux terminal.