Linux Environment Variables

By Vishvesh Patel · DevOps EngineerUpdated September 16, 2026

Shell versus exported variables, .bashrc versus .bash_profile, extending PATH without breaking it, and why sudo drops your environment.

What Environment Variables Are

Environment variables are named values that programs read at runtime. They are a simple way to pass configuration such as paths, usernames, regions, API endpoints, and feature flags into shells and processes.

Common examples include HOME, USER, SHELL, and PATH.

To inspect variables, you can use:

printenv
env
echo $HOME
echo $PATH
  • printenv prints environment variables
  • env shows the environment for the current process
  • echo $VAR prints one variable

Shell Variables vs Environment Variables

A shell can store local variables that only exist inside that shell session. A variable becomes part of the environment when you export it.

PROJECT_NAME=devops-platform
echo $PROJECT_NAME
export PROJECT_NAME
env | grep PROJECT_NAME

In that example:

  • PROJECT_NAME=... creates a shell variable
  • export PROJECT_NAME makes it available to child processes

This distinction matters because many tools only see exported variables.

Tip: If a script cannot see a variable that works in your terminal, check whether you exported it.

Scope and Process Inheritance

Environment variables are inherited downward. If you export a variable in one shell and start a child process, that child receives the variable. But the parent shell does not learn variables from the child.

Example:

export APP_ENV=staging
bash -c 'echo $APP_ENV'

The child bash process can read APP_ENV. If the child changes it, that change does not automatically flow back up to the original shell.

This one-way inheritance explains why scripts often need to be sourced when you want them to affect your current shell.

Persisting Variables Across Sessions

A variable set in the terminal normally disappears when the session ends. To make it persistent, place it in a startup file.

~/.bashrc

Used for interactive Bash shells. Good for aliases, exports, and shell customizations.

echo 'export EDITOR=vim' >> ~/.bashrc
source ~/.bashrc

~/.bash_profile and ~/.profile

These are read for login shells, depending on shell and distribution behavior. They are often used for variables that should exist at login time.

echo 'export APP_ENV=development' >> ~/.profile
source ~/.profile

/etc/environment

This file is system-wide and is often used for variables that should apply to many users. Its format is usually simple KEY=value lines rather than shell scripting.

sudo sh -c 'echo "JAVA_HOME=/usr/lib/jvm/java-21-openjdk" >> /etc/environment'

Note: Be careful with system-wide files. A bad edit can affect every user and service on the host.

Understanding PATH

PATH is one of the most important environment variables in Linux. It tells the shell where to look for executable commands.

View it with:

echo $PATH

You will usually see several directories separated by colons, such as /usr/local/bin:/usr/bin:/bin.

When you type python3, the shell searches those directories in order.

Adding a directory to PATH

For the current shell:

export PATH="$HOME/bin:$PATH"

To make it persistent for Bash:

echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Order matters. If two directories contain commands with the same name, the first one in PATH wins.

.env Files and Sourcing

Projects often keep environment settings in a .env file.

Example .env content:

APP_ENV=production
APP_PORT=8080
DATABASE_URL=postgres://app:secret@db:5432/app

A plain .env file is just text until you load it. One simple approach is sourcing a shell-friendly file:

set -a
source .env
set +a

set -a tells the shell to automatically export variables created while the file is sourced.

This pattern is useful for local development, but secrets in .env files should be handled carefully and usually should not be committed to Git.

A Practical Example

Suppose you installed a CLI tool into $HOME/bin, and the command is not found.

A sensible troubleshooting flow is:

echo $PATH
ls $HOME/bin
export PATH="$HOME/bin:$PATH"
which mytool

If that works, persist the PATH change in the appropriate profile file.

Environment variables are simple, but they influence many Linux workflows: shells, scripts, containers, systemd services, CI pipelines, and application configuration.

What You Should Remember

Use printenv, env, and echo $VAR to inspect environment data. Use export when child processes need access. Store persistent values in the right startup file, and understand that PATH controls command lookup order.

Once you are comfortable with environment variables, many Linux behaviors become easier to explain and troubleshoot.

Test Your Understanding

Exercise

Exercise 1: Exporting a variable

Why would you run `export APP_ENV=staging` instead of only `APP_ENV=staging`?

Exercise

Exercise 2: Understanding PATH

What is the main purpose of the PATH environment variable?

Exercise

Exercise 3: Persistent shell settings

Which file is commonly used to persist exports for an interactive Bash shell?


Frequently Asked Questions

What is the difference between a shell variable and an environment variable?

A shell variable exists only in the current shell, NAME=value creates one, and a child process knows nothing about it. export NAME=value promotes it to an environment variable, which is copied into every process the shell starts afterwards. That distinction explains most "my script cannot see the variable" problems: the variable was set but never exported, so the script ran in a child process that never received it. printenv lists exported variables; set lists everything.

Why does my variable disappear when I open a new terminal?

Because a variable set at the prompt lives only in that shell, and closing it discards everything. To persist one, add the export line to a startup file, ~/.bashrc for bash, ~/.zshrc for zsh, and either open a new shell or run source ~/.bashrc to apply it immediately. For values every user on the system should have, use /etc/environment or a file in /etc/profile.d/.

What is the difference between .bashrc and .bash_profile?

.bash_profile runs for login shells. An SSH session, or a console login. .bashrc runs for interactive non-login shells, which is what a new terminal tab on a desktop gives you. The practical consequence is that a variable set only in .bashrc is missing over SSH, and vice versa. The usual arrangement is to put everything in .bashrc and have .bash_profile source it, which most distributions already configure for you.

How do I add a directory to PATH permanently?

Add export PATH="$PATH:/opt/tool/bin" to ~/.bashrc, then source ~/.bashrc. Two details matter. Include $PATH in the value. Omitting it replaces your entire PATH and breaks almost every command until you open a new shell. And order decides precedence: a directory placed before $PATH wins over the system version, which is how you make a Homebrew or pyenv binary take priority over one in /usr/bin.

Why does sudo not see my environment variables?

Because sudo deliberately resets the environment for security. A user should not be able to influence a privileged command through PATH or LD_PRELOAD. Pass a value explicitly with sudo VAR=value command, preserve your environment with sudo -E command where policy allows, or use sudo -i for a full root login shell that reads root's own startup files. This is also why a script that works for you fails under sudo with "command not found".

Are environment variables a safe place for secrets?

They are better than a file committed to a repository and worse than a secrets manager. The problems are real: /proc/<pid>/environ exposes them to anyone who can read that process, they are inherited by every child process whether or not it should see them, they frequently end up in crash dumps and logs, and history captures the command that set them. For containers and Kubernetes they remain the normal interface, so the mitigation is to inject them at runtime from a secrets store rather than baking them into an image or a .env file in version control.

Continue Learning

Explore Related Topics

Try the Tool

Practise this in the browser

Linux Playground

Practise real shell commands in a simulated terminal.

When it breaks

Related Resources