Think environment variables are boring? Wait until one breaks your CI pipeline.
Linux stores key-value pairs that decide where programs look, what they can see, and what child processes inherit.
This reference lists the most useful variables, explains what each one does, and gives the exact commands you’ll run — printenv, env, set, declare, echo — plus quick examples for PATH, HOME, LANG, and friends.
Use it as a fast lookup, a one-line debug tool, and a list of gotchas to avoid late-night rollbacks.
Comprehensive Linux Environment Variables Reference

Linux keeps a set of environment variables that get passed down to child processes and control how programs behave, where they look for files, and what the system does by default. These are dynamic key-value pairs that stick around for your shell session (or until you change them). You can peek at them with printenv, env, and set, though each shows a slightly different view. For instance, printenv | less pages through every exported variable, printenv > env.txt dumps them to a file, and env | more shows them one screen at a time.
The distinction matters. printenv and env only show exported environment variables, the ones your child processes can see. set dumps everything: shell variables, functions, even unexported stuff like PS1 (your shell prompt) and TMOUT (shell timeout). Reach for printenv when you want a clean list of environment variables. Use set when you’re debugging shell behavior or hunting down a variable that exists locally but wasn’t exported. Filter with grep to narrow things down. printenv | grep HOME finds your home directory. printenv | grep -E -w 'HOME|PWD|USER' grabs multiple variables at once.
Variable size? Practically unlimited for normal use, though the theoretical cap sits around 32,760 characters for a single variable. The real limit comes from execve() system constraints and total environment size. Failures show up when you try to pass hundreds of megabytes. Check your system’s specifics with getconf -a | grep MAX and man 2 execve.
| Variable | Purpose | Example Value |
|---|---|---|
| PATH | Colon-separated list of directories searched for executables | /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
| HOME | User’s home directory | /home/alice |
| USER | Username of current user | alice |
| LOGNAME | Login name of current user | alice |
| SHELL | Path to user’s login shell | /bin/bash |
| PWD | Current working directory | /home/alice/projects |
| OLDPWD | Previous working directory | /home/alice |
| LANG | Default locale for language, character encoding, and formatting | en_US.UTF-8 |
| LC_ALL | Override for all locale categories | en_US.UTF-8 |
| TERM | Terminal type/emulation | xterm-256color |
| TMPDIR | Directory for temporary files | /tmp |
| EDITOR | Default text editor | vim |
| VISUAL | Preferred full-screen editor | nano |
| Location of user’s mail spool file | /var/mail/alice | |
| HISTSIZE | Number of commands stored in shell history | 1000 |
| HISTFILE | Path to shell history file | /home/alice/.bash_history |
| UID | Numeric user ID of current user | 1000 |
| EUID | Effective user ID (for permissions checks) | 1000 |
| PS1 | Primary shell prompt (typically unexported) | \u@\h:\w\$ |
| PS2 | Secondary shell prompt for multi-line commands | > |
Viewing Linux Environment Variables Using Core Commands

Commands that list variables split into two camps: ones that show only exported environment variables, and ones that show everything, including local and unexported shell variables. printenv and env display exported variables, the ones child processes inherit. set and declare show the full picture: local variables, functions, exported environment variables, all of it. If your script can’t see a variable, check whether it’s exported. If you’re tracking down shell behavior or a prompt variable, go with set.
Filtering large output is standard practice. Pipe to grep to search for specifics. env | grep PATH finds your executable search path. Use less or more to page through the full list. set | less works when you’re hunting for a function or local variable. Save output to a file for later comparison or audit. printenv > env.txt creates a snapshot you can diff against future sessions.
printenv VAR or printenv VAR1 VAR2 prints one or more exported variables. Run without arguments to list all. Example: printenv HOME gives you /home/alice.
env lists all exported environment variables. Can also run a command in a modified environment. Example: env | grep USER filters for user-related stuff.
set lists all shell variables and functions, including unexported ones like PS1 and TMOUT. Output’s large, so pipe to less for easier navigation.
declare shows shell variables and their attributes (exported, read-only, array). Run without arguments to list everything.
echo $VAR prints a single variable value. Works for both shell and environment variables. Example: echo $HOSTNAME might give you my-server.
Conceptual Categories of Linux Environment Variables

Grouping variables by category helps you navigate a big environment and understand which ones control specific behaviors. Instead of memorizing dozens of variable names, think in terms of user identity, directory paths, locale settings, terminal config, session state. The reference table in the first section lists individual variables. This section gives you the mental model for how they fit together.
Locale variables like LANG and LC_ALL control text rendering, character encoding, date formatting, sorting behavior. Terminal variables like TERM tell programs what escape sequences your terminal supports. Critical for tools like vim, less, and htop to display correctly. Session variables like XDG_SESSION_TYPE indicate whether you’re in a text console, X11, or Wayland session, which affects how desktop apps and display managers behave.
User-related categories include variables that identify who you are (USER, LOGNAME, UID, EUID) and influence permissions and ownership. Directory-path categories cover your working directory (PWD), home directory (HOME), temporary storage (TMPDIR). Execution-path categories center on PATH, which determines which binaries the shell finds when you type a command. Understanding these categories means you can predict which variables to check when something breaks. Wrong locale, missing executables, incorrect permissions.
User Identity
Directories
Locale
Terminal
Session
Execution Path
System-Wide vs User-Specific Linux Environment Variables

System-wide variables apply to all users. They’re typically set in /etc/environment, /etc/profile, or scripts in /etc/profile.d. Per-user variables live in shell startup files inside your home directory: ~/.bashrc, ~/.bash_profile, ~/.profile, or ~/.config/environment.d on systemd-based systems. System files run first, then user files. If a variable’s set in both places, your user setting usually wins because it loads last.
Shell login state determines which files run. SSH in or open a console? You get a login shell. ~/.bash_profile or ~/.profile runs. Open a new terminal window inside an existing session? You get a non-login interactive shell. ~/.bashrc runs. On many distributions, ~/.bash_profile sources ~/.bashrc, so variables in ~/.bashrc become available in login shells too. The systemd environment.d mechanism runs before the shell starts, making variables available to both graphical sessions and shell sessions.
| File | Scope | Supports Export? | Notes |
|---|---|---|---|
| /etc/environment | System-wide | No | Simple KEY=value pairs only; no variable expansion or shell syntax |
| /etc/profile | System-wide | Yes | Bash login shells; use export KEY=value here |
| /etc/profile.d/*.sh | System-wide | Yes | Sourced by /etc/profile; modular per-application exports |
| ~/.bashrc | Per-user | Yes | Non-login interactive shells; aliases, functions, shell settings |
| ~/.bash_profile | Per-user | Yes | Login shells (SSH, console); often sources ~/.bashrc |
| ~/.config/environment.d/*.conf | Per-user | No | Systemd session environment; KEY=value format |
Working With and Modifying the PATH Variable

PATH is a colon-separated list of directories the shell searches to find executables. Type ls? The shell walks through each directory in PATH from left to right until it finds /bin/ls. Prepending a directory gives it priority. Useful when you want your personal scripts to override system commands. Appending adds fallback locations, common for optional tools installed in /opt/bin or ~/bin.
Session changes are temporary. To make PATH modifications stick, add the export line to a startup file like ~/.bashrc or ~/.bash_profile. After editing, run source ~/.bashrc to reload the current shell or log out and back in.
Viewing PATH: echo $PATH displays the current search path. Example output: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Prepending directories: export PATH="$HOME/bin:$PATH" gives priority to ~/bin. Executables there get found first.
Appending directories: export PATH="$PATH:/opt/bin" adds /opt/bin at the end. It’s searched only if the executable isn’t found earlier.
Persisting changes: add the export line to ~/.bashrc or ~/.bash_profile, then run source ~/.bashrc to apply immediately.
Advanced Linux Environment Variable Usage in Shell Scripts

In scripts, you often need to handle missing variables gracefully or provide defaults. Parameter expansion syntax like ${VAR:-default} gives you a fallback if VAR is unset or empty. ${DATABASE_HOST:-localhost} uses localhost when DATABASE_HOST isn’t defined. Quoting variables is critical to avoid word splitting and glob expansion. Always use "$VAR" instead of $VAR unless you specifically want the shell to split the value on whitespace.
Testing whether a variable is set requires checking exit codes or using built-in tests. Run printenv VAR >/dev/null and check $?. Exit code 0 means the variable is set, non-zero means it’s not. In Bash, [ -v VAR ] tests whether a variable is set (even if it’s empty), and ${VAR+x} expands to x if VAR is set.
Assigning variables inline for a single command is common in scripts. DEBUG=1 my_app runs my_app with DEBUG set to 1 for that process only. The variable doesn’t persist in the parent shell. This pattern’s useful for toggling behavior without changing the environment permanently.
Safe Parameter Expansion Techniques
Use ${VAR:-default} when you want a fallback value if VAR is unset or empty. ${CONFIG_FILE:-/etc/app.conf} defaults to /etc/app.conf. Use ${VAR:=default} to assign the default if VAR is unset or empty. The variable gets set, not just substituted. For distinguishing unset from empty, ${VAR-default} substitutes only if VAR is unset (ignores empty), and ${VAR+set} expands to set when VAR is defined, even if it’s empty. Always quote expansions. "${VAR:-default}" prevents the shell from splitting the result into multiple arguments.
Persistent, Temporary, and One-Off Linux Environment Variables

Variables have different lifetimes depending on how you create them. A temporary variable set with VAR=value exists only in the current shell. An exported variable created with export VAR=value is inherited by child processes but lost when the shell exits. A persistent variable is one you’ve added to a startup file like ~/.bashrc or ~/.bash_profile. It’s recreated every time you log in.
One-off assignments work well for testing or single commands. Running LOG_LEVEL=debug ./server sets LOG_LEVEL for that process only. The parent shell and future commands don’t see it. This pattern’s safer than exporting because it limits the scope of change.
Unsetting removes a variable from the environment. Run unset VAR to delete it. Verify with printenv VAR (empty output) or echo $VAR (also empty). After unsetting, the variable won’t be inherited by new processes unless you recreate it.
Temporary inline assignment: VAR=value command sets VAR for that single command. Example: LANG=C sort file.txt
Exporting: export VAR=value makes VAR available to child processes. Lasts for the session but not across logins.
Persistent configuration: add export VAR=value to ~/.bashrc or ~/.bash_profile. Reload with source ~/.bashrc.
Unsetting: unset VAR removes the variable. Verify with printenv VAR or echo $VAR.
Loading from .env: many projects use .env files with KEY=value lines. Load them with export $(grep -v '^#' .env | xargs) or use a tool like dotenv.
Linux Environment Variables in Containers, Cron, and Systemd

Environment variables behave differently in specialized contexts. Cron jobs run with a minimal environment, usually just HOME, LOGNAME, SHELL, and a restricted PATH (often /usr/bin:/bin). If a cron script depends on variables or executables in /usr/local/bin, it’ll fail unless you set PATH explicitly in the crontab or script. Always define critical variables at the top of cron scripts or in the crontab preamble.
Docker containers inherit variables passed with -e or --env-file at runtime. docker run -e DATABASE_URL=postgres://db:5432/app myimage makes DATABASE_URL available inside the container. Variables defined in the Dockerfile with ENV are baked into the image. Compose files support environment: blocks and .env file references.
Systemd services use Environment= directives in unit files to set variables. You can also modify the environment at runtime with systemctl set-environment VAR=value (system-wide) or systemctl --user set-environment VAR=value (per-user). Unlike shell exports, systemd variables apply to all services managed by that instance.
| Context | Behavior | How to Set | Notes |
|---|---|---|---|
| Cron | Minimal environment; restricted PATH | Define in crontab preamble or script header | Common cron PATH: /usr/bin:/bin; expand as needed |
| Docker | Isolated environment; inherits passed variables | docker run -e VAR=value or ENV in Dockerfile | Use –env-file for bulk variable injection |
| Systemd unit | Environment set per service; no shell inheritance | Environment=VAR=value in [Service] section | Supports EnvironmentFile= for .env-style files |
| Systemctl runtime | System-wide or per-user; affects all managed services | systemctl set-environment VAR=value | Persists until reboot; use unset-environment to remove |
Debugging and Validating Linux Environment Variables

When a script or command fails because of a missing or incorrect variable, start by listing the environment as the process sees it. Run printenv | grep VAR to check whether a specific variable is set. Use printenv | sort to see all variables in alphabetical order. Easier to scan than unsorted output. Save a snapshot with printenv > env_snapshot.txt and compare it later with diff to track changes between sessions or after modifying startup files.
For full shell state including functions and unexported variables, use set | less and search with /. Check exit codes to test whether a variable is set. printenv DATABASE_URL >/dev/null && echo "set" || echo "unset" gives a quick yes/no answer. In scripts, use ${VAR+x} to distinguish unset from set-but-empty. If VAR is defined (even as an empty string), ${VAR+x} expands to x.
printenv | grep KEYWORD filters environment variables by keyword. Example: printenv | grep -i lang finds locale-related variables.
printenv | sort lists all variables in alphabetical order for easier scanning.
set | less pages through all shell variables and functions. Use / to search.
printenv > snapshot.txt saves current environment to a file for later comparison or audit.
Final Words
We jumped straight into listing and inspecting variables with printenv, env, and set, plus quick filtering with grep and paging tools.
Then we covered when to use each command, PATH best practices, where to make changes persistent (/etc/environment, ~/.bashrc), and script-safe patterns like ${VAR:-default}. We also noted size limits and ways to capture env output for debugging.
Keep this linux environment variables list handy as a quick lookup. Try the commands and you’ll get more predictable, easier-to-debug shells.
FAQ
Q: How to list all env variables in Linux?
A: The way to list all environment variables in Linux is to run printenv or env for exported vars, use set to include shell-only variables, and pipe to grep/less or redirect to a file for inspection.
Q: What are the environment variables in Linux?
A: Environment variables in Linux are key=value pairs inherited by processes that configure behavior—common ones include PATH, HOME, USER, SHELL, LANG, and TMPDIR; they control paths, locale, temp dirs, and user identity.
