Env_vars
Chapter 26: Environment Variables in Bash
Section titled “Chapter 26: Environment Variables in Bash”Overview
Section titled “Overview”Environment variables are named values that affect how processes run. They are crucial for configuration, secrets management, and controlling program behavior in DevOps environments.
Understanding Environment Variables
Section titled “Understanding Environment Variables”What are Environment Variables?
Section titled “What are Environment Variables?”Environment variables are key-value pairs that:
- Configure system and application behavior
- Store user preferences
- Hold sensitive information (credentials, tokens)
- Enable process communication
┌────────────────────────────────────────────────────────────────┐│ Environment Variable Flow │├────────────────────────────────────────────────────────────────┤│ ││ Shell Startup ││ ──────────── ││ ││ /etc/profile ──┐ ││ ~/.bash_profile ──┼──► Environment Variables ││ ~/.bashrc ──┘ ││ ││ │ ││ ▼ ││ Process gets copy ││ │ ││ ▼ ││ Child processes inherit ││ ││ ┌───────┐ ┌───────┐ ┌───────┐ ││ │ bash │────►│ nginx │────►│ app │ ││ └───────┘ └───────┘ └───────┘ ││ ││ Each gets its own copy ││ │└────────────────────────────────────────────────────────────────┘Viewing Environment Variables
Section titled “Viewing Environment Variables”printenv
Section titled “printenv”# Print all environment variablesprintenv
# Print specific variableprintenv HOMEprintenv PATHprintenv USER
# Print with grepprintenv | grep -i path# List all environment variablesenv
# Run command with modified envenv VAR=value command
# Remove variableenv -u VAR commandCommon System Variables
Section titled “Common System Variables”Essential Variables
Section titled “Essential Variables”# User informationecho $USER # Current usernameecho $HOME # Home directoryecho $UID # User IDecho $GID # Group ID
# Shell informationecho $SHELL # Default shellecho $PWD # Current directoryecho $OLDPWD # Previous directory
# System informationecho $HOSTNAME # Host nameecho $HOSTTYPE # Machine typeecho $ARCH # Architecture
# Pathecho $PATH # Executable search pathecho $PATH # Separate with: # export PATH="/new/path:$PATH"
# Terminalecho $TERM # Terminal typeecho $LINES # Terminal linesecho $COLUMNS # Terminal columnsLanguage and Locale
Section titled “Language and Locale”echo $LANG # Default languageecho $LC_ALL # Locale overrideecho $LANGUAGE # Language priorityecho $TZ # TimezoneSetting Variables
Section titled “Setting Variables”Temporary Variables
Section titled “Temporary Variables”# Set variable (current shell only)MY_VAR="value"
# Export for child processesexport MY_VAR="value"
# Combinedexport MY_VAR="value"
# Or equivalentlydeclare -x MY_VAR="value"Persistent Variables
Section titled “Persistent Variables”~/.bashrc
Section titled “~/.bashrc”# Add to ~/.bashrcexport EDITOR=vimexport VISUAL=vimexport PATH="/home/user/bin:$PATH"export MY_VARIABLE="value"
# Reloadsource ~/.bashrc~/.bash_profile (or ~/.profile)
Section titled “~/.bash_profile (or ~/.profile)”# Add to ~/.bash_profileexport PATH="$HOME/bin:$PATH"export EDITOR=vim
# For system-wide, edit:# /etc/environment# /etc/profile# /etc/profile.d/*.shVariable Scope
Section titled “Variable Scope”Shell vs Environment
Section titled “Shell vs Environment”# Shell variable (not exported)MY_VAR="shell_only"echo $MY_VAR
# Export to environmentexport MY_VARprintenv MY_VAR # Now visibleInheritance
Section titled “Inheritance”# Parent exports variableexport MY_VAR="parent_value"
# Child inheritsbash -c 'echo $MY_VAR'
# Child cannot affect parentbash -c 'export MY_VAR="child_value"'echo $MY_VAR # Still parent_valueSpecial Variable Operations
Section titled “Special Variable Operations”unset - Remove Variable
Section titled “unset - Remove Variable”# Remove variableunset MY_VAR
# Remove exported variableunset -v MY_VAR
# Remove functionunset -f my_functionreadonly - Make Immutable
Section titled “readonly - Make Immutable”# Read-only variablereadonly MY_CONST="value"MY_CONST="new" # Error
# Read-only functionreadonly -f my_functiondeclare - Variable Declaration
Section titled “declare - Variable Declaration”# Declare variabledeclare -x MY_VAR="value" # Exporteddeclare +x MY_VAR # Remove exportdeclare -r MY_VAR="value" # Read-onlydeclare -i MY_VAR=5 # Integerdeclare -a MY_ARRAY=(a b c) # Arraydeclare -A MY_ASSOC=( [key]=value ) # AssociativeAdvanced Topics
Section titled “Advanced Topics”Parameter Expansion in Variables
Section titled “Parameter Expansion in Variables”# Default valueecho ${VAR:-default} # Use default if unset/null
# Assign defaultecho ${VAR:=default} # Set if unset/null
# Use alternate value if setecho ${VAR:+alternate} # Use alternate if set
# Error if unsetecho ${VAR:?error} # Print error if unset
# Remove pattern${VAR#pattern} # Remove shortest match from start${VAR##pattern} # Remove longest match from start${VAR%pattern} # Remove shortest match from end${VAR%%pattern} # Remove longest match from endArray from Environment
Section titled “Array from Environment”# Export array-like variableexport MY_LIST="one:two:three"
# Read as arrayIFS=':' read -ra ARR <<< "$MY_LIST"echo "${ARR[0]}" # one
# Alternative: multiple exportsexport MY_VAR_1="value1"export MY_VAR_2="value2"Real-World DevOps Examples
Section titled “Real-World DevOps Examples”Application Configuration
Section titled “Application Configuration”#!/usr/bin/env bash# Application startup with environment
# Configurationexport APP_NAME="myapp"export APP_ENV="${APP_ENV:-production}"export APP_PORT="${APP_PORT:-8080}"export APP_HOST="${APP_HOST:-0.0.0.0}"export LOG_LEVEL="${LOG_LEVEL:-info}"
# Databaseexport DB_HOST="${DB_HOST:-localhost}"export DB_PORT="${DB_PORT:-5432}"export DB_NAME="${DB_NAME:-appdb}"export DB_USER="${DB_USER:-appuser}"
# Start applicationecho "Starting $APP_NAME in $APP_ENV mode"./bin/$APP_NAMESecrets Management
Section titled “Secrets Management”#!/usr/bin/env bash# Load secrets from file
SECRETS_FILE="/etc/myapp/secrets"
if [[ -f "$SECRETS_FILE" ]]; then set -a # Auto-export source "$SECRETS_FILE" set +afi
# Now use variablesecho "Database: $DB_PASSWORD" | head -c 5# ****Docker Environment
Section titled “Docker Environment”#!/usr/bin/env bash# Docker environment variables
# Docker sets these automaticallyecho "Image: $IMAGE_NAME"echo "Container: $HOSTNAME"
# User-definedecho "Config: $MY_CONFIG"
# All env in containerenv | sortKubernetes Environment
Section titled “Kubernetes Environment”#!/usr/bin/env bash# Kubernetes environment variables
# Kubernetes injects:echo "Pod: $POD_NAME"echo "Namespace: $NAMESPACE"echo "Node: $NODE_NAME"
# Container resourcesecho "CPU limit: $CPU_LIMIT"echo "Memory limit: $MEMORY_LIMIT"
# ConfigMap valuesecho "Config: $CONFIG_KEY"
# Secret valuesecho "Secret: $SECRET_KEY"PATH Management
Section titled “PATH Management”Adding to PATH
Section titled “Adding to PATH”# Add to beginning (takes precedence)export PATH="/usr/local/bin:$PATH"
# Add to endexport PATH="$PATH:/usr/local/bin"
# Add multipleexport PATH="/opt/bin:/usr/local/bin:$PATH"
# Conditional additionif [[ ":$PATH:" != *":/custom/bin:"* ]]; then export PATH="/custom/bin:$PATH"fiFinding Commands
Section titled “Finding Commands”# Find command locationwhich pythonwhich -a python # All occurrenceswhereis python # Binary, source, man pages
# Check if in PATHcommand -v python # Returns path or emptytype python # Shows typeEnvironment Files
Section titled “Environment Files”/etc/environment
Section titled “/etc/environment”# Simple format (no export)VAR1=value1VAR2=value2/etc/profile.d/
Section titled “/etc/profile.d/”# Create custom.shsudo tee /etc/profile.d/custom.sh <<'EOF'export CUSTOM_VAR="value"export PATH="/opt/custom/bin:$PATH"EOF
# Makes available to all users on loginsystemd Service Environment
Section titled “systemd Service Environment”# In service file[Service]Environment="VAR1=value1"EnvironmentFile=/etc/myapp/envExecStart=/usr/bin/myapp
# Environment file format# VAR=value# Lines starting with # are commentsSecurity Considerations
Section titled “Security Considerations”Sensitive Data
Section titled “Sensitive Data”# Never store secrets in environment variables that persist# - .bashrc# - .bash_history# - Log files
# Use secret management tools instead:# - HashiCorp Vault# - AWS Secrets Manager# - Kubernetes Secrets
# Example: Kubernetes Secret# kubectl create secret generic db-creds \# --from-literal=username=admin \# --from-literal=password=secretBest Practices
Section titled “Best Practices”# Don't put secrets in version control# .gitignore:# Use .env files with loading mechanismif [[ -f .env ]]; then set -a source .env set +afi
# .env should contain:# APP_KEY=xxxxx# DATABASE_PASSWORD=xxxxx# API_TOKEN=xxxxxDebugging Environment
Section titled “Debugging Environment”Show Environment Changes
Section titled “Show Environment Changes”#!/usr/bin/env bash# Debug environment
echo "=== Original Environment ==="env | sort > /tmp/env_before
# Run command"$@"
echo "=== New Environment ==="env | sort > /tmp/env_after
# Comparediff /tmp/env_before /tmp/env_afterSummary
Section titled “Summary”In this chapter, you learned:
- ✅ What environment variables are
- ✅ Viewing variables (printenv, env)
- ✅ Common system variables
- ✅ Setting variables (temporary and persistent)
- ✅ Variable scope and inheritance
- ✅ Special operations (unset, readonly, declare)
- ✅ Parameter expansion
- ✅ Real-world DevOps examples
- ✅ PATH management
- ✅ Environment files (/etc/environment, profile.d/)
- ✅ Security considerations
Next Steps
Section titled “Next Steps”Continue to the next chapter to learn about Shell Expansion.
Previous Chapter: Job Control Next Chapter: Shell Expansion