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 commandsHOME— current user's home directoryUSER/LOGNAME— current usernameSHELL— path to the current shell binaryEDITOR— default text editorLANG/LC_ALL— locale and language settingsPS1— the shell prompt formatTMPDIR— 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.