Linux Environment Variables: .bashrc, .profile, and export

Environment variables control how programs and the shell behave. They store configuration like the system path, the default editor, language settings, and application-specific values like database URLs or API keys. Understanding how they work — and how to set them permanently — is foundational Linux knowledge.

What Are Environment Variables?

An environment variable is a named value stored in the shell's environment. Programs can read these values at runtime. The shell itself uses them for configuration.

printenv                          # Print all environment variables
printenv PATH                     # Print a specific variable
echo $HOME                        # Access variable with $ prefix
echo $USER                        # Current username
echo $SHELL                       # Current shell
echo $PWD                         # Current directory (same as pwd)
echo $TERM                        # Terminal type

Important Default Variables

  • PATH — colon-separated list of directories the shell searches for commands
  • HOME — current user's home directory
  • USER / LOGNAME — current username
  • SHELL — path to the current shell binary
  • EDITOR — default text editor
  • LANG / LC_ALL — locale and language settings
  • PS1 — the shell prompt format
  • TMPDIR — directory for temporary files

Setting Variables in the Current Session

MY_VAR="hello"           # Set a shell variable (not exported to child processes)
export MY_VAR="hello"    # Export: available to the shell and all child processes
export MY_VAR            # Export an already-defined variable

unset MY_VAR             # Remove variable

Variables set without export are local to the current shell. They will not be passed to programs you run from that shell.

The PATH Variable

PATH tells the shell where to look for commands. When you type nginx, the shell searches each directory in PATH in order until it finds the executable.

echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/alok/.local/bin

# Add a directory to PATH for the current session
export PATH="$PATH:/opt/myapp/bin"

# Check where a command is found
which nginx
which python3

Making Variables Permanent

The right file depends on the scope you need:

~/.bashrc — Interactive Non-Login Shells

Sourced every time you open a new terminal window (but not on SSH login without a shell). Best for aliases, functions, and non-login interactive settings.

nano ~/.bashrc

# Add at the bottom:
export EDITOR=vim
export PATH="$PATH:/opt/myapp/bin"
alias ll="ls -lah"
alias gs="git status"

~/.bash_profile or ~/.profile — Login Shells

Sourced on SSH login and console login. Use for environment variables that all processes started by this user should inherit.

nano ~/.profile

# Add:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export PATH="$PATH:$JAVA_HOME/bin"
export DB_HOST=localhost
export DB_NAME=myapp_db

/etc/environment — System-Wide, All Users

This file is read by PAM on login. It is not a shell script — just KEY=VALUE pairs, no export needed, no variable expansion.

sudo nano /etc/environment

# Contents:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
LANG="en_US.UTF-8"
JAVA_HOME="/usr/lib/jvm/java-17-openjdk"

/etc/profile and /etc/profile.d/

/etc/profile is sourced for all users on login. Drop scripts into /etc/profile.d/ to add system-wide variables without editing the main file:

sudo nano /etc/profile.d/myapp.sh

export APP_ENV=production
export APP_LOG=/var/log/myapp

Applying Changes

source ~/.bashrc             # Reload .bashrc in current session
source ~/.profile            # Reload .profile
. ~/.bashrc                  # Same as source (dot command)

exec bash                    # Start a new bash session (cleaner reload)

Variables in Scripts and Services

# In a script: load variables from a file
source /etc/myapp/config.env

# Or use env file with systemd
# /etc/systemd/system/myapp.service
# EnvironmentFile=/etc/myapp/myapp.env

A Secure .env File Pattern

sudo nano /etc/myapp/myapp.env
# DB_HOST=localhost
# DB_USER=appuser
# DB_PASS=s3cr3t
# APP_ENV=production

sudo chmod 600 /etc/myapp/myapp.env
sudo chown root:root /etc/myapp/myapp.env

Never commit .env files with secrets to version control.

Debugging Variable Issues

env                          # All exported variables (same as printenv)
bash -x myscript.sh          # Debug script execution, prints each command
set -o                       # Show shell options
type my_command              # Check if command is function, alias, or binary

Summary

Environment variables configure the runtime environment for the shell and every program it runs. Use ~/.bashrc for interactive shell customizations, ~/.profile for login-time variables, and /etc/environment for system-wide settings. Keep secrets out of shell history and version control — use restricted .env files instead.