AtomLearnAtomLearn
DashboardGoalsPathAchievementsReviewSign In
DashboardLinux & Command LineEnvironment Variables
Linux & Command LineNot Started

Environment Variables

Configure apps with environment variables — the standard for secrets, config, and runtime settings

0%
Knowledge0%
Learn & Drill
Fluency0%
Drill & Speed
Retention0%
Mastery & Review
Confidence0%
All modes
Practice

Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.

Upgrade
Knowledge
Fluency
Retention

Knowledge Debt detected

You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.

Explanation

Environment variables are key-value pairs available to a process and all its children. They are the standard way to configure apps differently across environments (dev, staging, prod) without changing code.

Viewing and setting variables:

bash env # list all environment variables printenv HOME # print a specific variable echo $HOME # same — $ expands the variable echo $PATH # the directories searched for executables # Set in current shell (not persistent) export DATABASE_URL="postgresql://localhost/mydb" export DEBUG=true # Set for a single command (does not pollute the shell) DEBUG=true python app.py NODE_ENV=production node server.js

PATH — how the shell finds commands:

bash echo $PATH # /usr/local/bin:/usr/bin:/usr/sbin:/home/bill/.local/bin # Add a directory to PATH export PATH="$PATH:/opt/my-tools/bin" # Verify a command will be found which python3 # /usr/bin/python3

Making variables persistent — shell config files:

bash # For interactive shells: ~/.bashrc (bash) or ~/.zshrc (zsh) echo 'export EDITOR=vim' >> ~/.bashrc echo 'export GOPATH=$HOME/go' >> ~/.bashrc source ~/.bashrc # reload without restarting terminal # For login shells: ~/.bash_profile or ~/.profile # Rule of thumb: put exports in ~/.bashrc (most configs work there)

The .env file pattern (12-factor apps):

bash # .env file — never commit to git! DATABASE_URL=postgresql://localhost/mydb SECRET_KEY=supersecretvalue STRIPE_KEY=sk_live_abc123 DEBUG=false # Load with Python-dotenv # from dotenv import load_dotenv; load_dotenv() # Load with bash set -a; source .env; set +a # set -a marks all subsequent assignments for export # Always add .env to .gitignore echo ".env" >> .gitignore

Variable expansion:

bash NAME="Bill" echo "Hello, $NAME" # Hello, Bill echo "Home: ${HOME}" # use braces for clarity with adjacent text echo "${NAME:-default}" # use "default" if NAME is unset or empty echo "${NAME:?error msg}" # error and exit if NAME is unset (great in scripts)

Examples

Configuring a Flask app with environment variables

os.environ["KEY"] raises KeyError if missing (good — fail fast). os.getenv("KEY", default) returns the default if missing.

# .env (never commit this!)
FLASK_ENV=development
DATABASE_URL=postgresql://bill:secret@localhost/myapp
SECRET_KEY=dev-only-secret-do-not-use-in-prod
REDIS_URL=redis://localhost:6379

# app.py — read from environment, not hardcoded
import os
from dotenv import load_dotenv

load_dotenv()  # reads .env file into os.environ

DATABASE_URL = os.environ["DATABASE_URL"]   # fails fast if missing
DEBUG = os.getenv("DEBUG", "false").lower() == "true"  # optional with default

# In production (Heroku, Railway, Vercel) — set via dashboard
# No .env file needed — the platform injects the variables

# Never do this:
# DATABASE_URL = "postgresql://bill:secret@prod-db/myapp"  — hardcoded secret!

Managing PATH and persistent exports

Prefix-style KEY=value command is clean for one-off overrides — CI pipelines use this pattern heavily.

# See the current PATH
echo $PATH
# /usr/local/bin:/usr/bin:/usr/sbin:/home/bill/.local/bin

# Install a tool to ~/bin and add it to PATH
mkdir -p ~/bin
cp my-script.sh ~/bin/my-script

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

# Verify it works
which my-script
# /home/bill/bin/my-script
my-script

# Set a variable for one command only (does not affect shell)
DATABASE_URL=postgresql://test-db python -m pytest

# Debug: see what a child process will receive
env DATABASE_URL=test python -c "import os; print(os.environ['DATABASE_URL'])"
# test

How well did you understand this?

Next in Linux & Command Line

Cron Jobs

Continue