Linux Tutorial — Part 10: Environment Variables & System Configuration

By Suraj Ahir December 21, 2025 6 min read

Linux — Logging & Monitoring
Linux — Logging & Monitoring
← Part 9 Linux Tutorial · Part 10 of 12 Part 11 →

Environment variables are a key mechanism in Linux for configuring how programs behave without hardcoding settings. Every professional deployment uses environment variables to manage configuration across different environments — development, staging, production. Understanding them deeply matters for every developer and operations engineer.

What Are Environment Variables?

Environment variables are named values stored in the shell's environment. Every process inherits environment variables from its parent. They configure system behavior, set paths for finding executables, and provide configuration to applications without modifying code.

Working with Environment Variables
env                             # Print all environment variables
printenv                        # Same as env
echo $HOME                      # Print specific variable
echo $PATH                      # Show executable search paths
echo $USER                      # Current username
echo $SHELL                     # Current shell
echo $PWD                       # Current directory

# Set a variable (current session only)
export DATABASE_URL="postgresql://localhost/mydb"
export APP_ENV="production"
export PORT=8080

# Unset a variable
unset DATABASE_URL

Making Variables Persistent

Persistent Configuration
# User-level — add to ~/.bashrc or ~/.bash_profile
echo 'export JAVA_HOME="/usr/lib/jvm/java-17"' >> ~/.bashrc
echo 'export PATH="$PATH:$JAVA_HOME/bin"' >> ~/.bashrc
source ~/.bashrc    # Apply changes without restarting shell

# System-level — for all users
sudo nano /etc/environment
# Add: MY_GLOBAL_VAR="value"

# Or in /etc/profile.d/
sudo nano /etc/profile.d/myapp.sh
# Add exports there

PATH — The Most Important Variable

PATH determines where Linux looks for executable programs when you type a command. Understanding PATH helps you install software correctly and troubleshoot "command not found" errors:

PATH Management
echo $PATH                              # See current PATH
which python3                           # Where is python3 found?
which: no mycommand in ($PATH)          # What "command not found" means

# Add to PATH
export PATH="$PATH:/home/suraj/.local/bin"
export PATH="/usr/local/go/bin:$PATH"  # Add to front (higher priority)

Configuration Files Overview

Key Configuration Files
/etc/hostname               # System hostname
/etc/hosts                  # Local DNS — override DNS for specific names
/etc/fstab                  # Filesystem mount points
/etc/sudoers                # Sudo permissions (edit with visudo!)
/etc/ssh/sshd_config        # SSH server configuration
/etc/crontab                # System-wide cron jobs
/etc/sysctl.conf            # Kernel parameters
/etc/environment            # System-wide environment variables
~/.bashrc                   # User shell config (runs for interactive shells)
~/.bash_profile             # User login config (runs at login)
~/.ssh/config               # SSH client configuration

Managing /etc/hosts

/etc/hosts Usage
cat /etc/hosts
# 127.0.0.1    localhost
# Add custom entries:
sudo bash -c 'echo "192.168.1.50  staging.internal" >> /etc/hosts'
sudo bash -c 'echo "10.0.1.10    database.internal" >> /etc/hosts'

Using .env Files in Applications

Modern applications typically use .env files for local development and real environment variables in production:

.env Pattern
# .env file — never commit to git
DATABASE_URL=postgresql://localhost/myapp_dev
SECRET_KEY=dev-secret-key-change-in-prod
REDIS_URL=redis://localhost:6379
DEBUG=true

# Load with bash
export $(cat .env | grep -v '^#' | xargs)

# Load with Python dotenv
from dotenv import load_dotenv
load_dotenv()

In Part 11, we will cover disk management — understanding file systems, mounting, and managing storage in Linux.

Profile Files and Shell Initialization Order

When you open a terminal, Linux executes files in a specific order to set up your environment. For SSH login sessions: /etc/profile runs first system-wide, then ~/.bash_profile or ~/.profile for the user. For interactive terminal sessions: /etc/bash.bashrc runs system-wide, then ~/.bashrc for the user. Most user-specific configuration belongs in ~/.bashrc on Ubuntu/Debian systems. Changes take effect for new shells. Use source ~/.bashrc to apply changes immediately to the current session. A well-maintained ~/.bashrc stored in a git repository is a personal productivity asset you can deploy to any new machine.

Managing Multiple Versions with update-alternatives

When multiple versions of a tool are installed, update-alternatives manages which version commands resolve to. sudo update-alternatives --config python3 shows available Python 3 versions and lets you select the default interactively. sudo update-alternatives --list java shows configured Java alternatives. This system is cleaner than manually editing symlinks and prevents the confusion of installing a new tool version and having the command still point to the old one. On RHEL/CentOS, the equivalent is the alternatives command with identical syntax.

Practice Exercise

Customize your shell environment by editing ~/.bashrc: add three useful aliases (alias ll='ls -la --color=auto', alias ..='cd ..', alias grep='grep --color=auto'), customize your PS1 prompt to show username, hostname, and current directory in different colors, and add a function that creates a directory and immediately changes into it (mkcd() { mkdir -p "$1" && cd "$1"; }). Run source ~/.bashrc to apply changes. Then use printenv to see all environment variables and identify three you were not previously aware of.

Linux in Your Daily Engineering Practice

Linux command-line proficiency is not something you learn once and then stop improving. It is a skill that deepens continuously as you encounter new tools, new use cases, and new problems to solve. The engineers who are most effective at the command line did not become that way by reading comprehensive guides — they became that way by spending years solving real problems at the terminal, gradually accumulating a toolkit of commands, aliases, scripts, and muscle memory. The best approach is to use Linux for real work as much as possible, to look up better ways to do things you already do, and to make note of efficient patterns you observe in others' work. Over time, the terminal becomes faster than any GUI for the tasks you do repeatedly.

Putting It All Together

Every topic in technology and finance rewards the learner who goes beyond surface understanding to build genuine fluency. Fluency comes from repeated exposure, application in varied contexts, and reflection on what worked and what did not. The concepts discussed here are starting points — each one opens into a deeper field of study that could occupy years of focused learning. The most effective approach is not to try to master everything at once, but to pick the areas most relevant to your current goals, go deep there, and then expand. Depth in a few areas is more valuable than shallow familiarity with many. Build on what you know, stay curious about what you do not, and keep the practice of learning as a consistent daily habit rather than an occasional burst of effort.

The questions that make learning stick: How does this connect to what I already know? Where would I actually use this? What would happen if I tried to explain this to someone who knows nothing about it? What are the edge cases and exceptions? What is still unclear? Asking these questions transforms passive reading into active learning, and active learning is what builds the kind of understanding that is still accessible years later when you need it under real conditions.

Disclaimer: Educational content only. Practice is required for real skill development.