Skip to content

Env_vars

Environment variables are named values that affect how processes run. They are crucial for configuration, secrets management, and controlling program behavior in DevOps environments.


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 │
│ │
└────────────────────────────────────────────────────────────────┘

Terminal window
# Print all environment variables
printenv
# Print specific variable
printenv HOME
printenv PATH
printenv USER
# Print with grep
printenv | grep -i path
Terminal window
# List all environment variables
env
# Run command with modified env
env VAR=value command
# Remove variable
env -u VAR command

Terminal window
# User information
echo $USER # Current username
echo $HOME # Home directory
echo $UID # User ID
echo $GID # Group ID
# Shell information
echo $SHELL # Default shell
echo $PWD # Current directory
echo $OLDPWD # Previous directory
# System information
echo $HOSTNAME # Host name
echo $HOSTTYPE # Machine type
echo $ARCH # Architecture
# Path
echo $PATH # Executable search path
echo $PATH # Separate with:
# export PATH="/new/path:$PATH"
# Terminal
echo $TERM # Terminal type
echo $LINES # Terminal lines
echo $COLUMNS # Terminal columns
Terminal window
echo $LANG # Default language
echo $LC_ALL # Locale override
echo $LANGUAGE # Language priority
echo $TZ # Timezone

Terminal window
# Set variable (current shell only)
MY_VAR="value"
# Export for child processes
export MY_VAR="value"
# Combined
export MY_VAR="value"
# Or equivalently
declare -x MY_VAR="value"
Terminal window
# Add to ~/.bashrc
export EDITOR=vim
export VISUAL=vim
export PATH="/home/user/bin:$PATH"
export MY_VARIABLE="value"
# Reload
source ~/.bashrc
Terminal window
# Add to ~/.bash_profile
export PATH="$HOME/bin:$PATH"
export EDITOR=vim
# For system-wide, edit:
# /etc/environment
# /etc/profile
# /etc/profile.d/*.sh

Terminal window
# Shell variable (not exported)
MY_VAR="shell_only"
echo $MY_VAR
# Export to environment
export MY_VAR
printenv MY_VAR # Now visible
Terminal window
# Parent exports variable
export MY_VAR="parent_value"
# Child inherits
bash -c 'echo $MY_VAR'
# Child cannot affect parent
bash -c 'export MY_VAR="child_value"'
echo $MY_VAR # Still parent_value

Terminal window
# Remove variable
unset MY_VAR
# Remove exported variable
unset -v MY_VAR
# Remove function
unset -f my_function
Terminal window
# Read-only variable
readonly MY_CONST="value"
MY_CONST="new" # Error
# Read-only function
readonly -f my_function
Terminal window
# Declare variable
declare -x MY_VAR="value" # Exported
declare +x MY_VAR # Remove export
declare -r MY_VAR="value" # Read-only
declare -i MY_VAR=5 # Integer
declare -a MY_ARRAY=(a b c) # Array
declare -A MY_ASSOC=( [key]=value ) # Associative

Terminal window
# Default value
echo ${VAR:-default} # Use default if unset/null
# Assign default
echo ${VAR:=default} # Set if unset/null
# Use alternate value if set
echo ${VAR:+alternate} # Use alternate if set
# Error if unset
echo ${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 end
Terminal window
# Export array-like variable
export MY_LIST="one:two:three"
# Read as array
IFS=':' read -ra ARR <<< "$MY_LIST"
echo "${ARR[0]}" # one
# Alternative: multiple exports
export MY_VAR_1="value1"
export MY_VAR_2="value2"

#!/usr/bin/env bash
# Application startup with environment
# Configuration
export 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}"
# Database
export DB_HOST="${DB_HOST:-localhost}"
export DB_PORT="${DB_PORT:-5432}"
export DB_NAME="${DB_NAME:-appdb}"
export DB_USER="${DB_USER:-appuser}"
# Start application
echo "Starting $APP_NAME in $APP_ENV mode"
./bin/$APP_NAME
#!/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 +a
fi
# Now use variables
echo "Database: $DB_PASSWORD" | head -c 5
# ****
#!/usr/bin/env bash
# Docker environment variables
# Docker sets these automatically
echo "Image: $IMAGE_NAME"
echo "Container: $HOSTNAME"
# User-defined
echo "Config: $MY_CONFIG"
# All env in container
env | sort
#!/usr/bin/env bash
# Kubernetes environment variables
# Kubernetes injects:
echo "Pod: $POD_NAME"
echo "Namespace: $NAMESPACE"
echo "Node: $NODE_NAME"
# Container resources
echo "CPU limit: $CPU_LIMIT"
echo "Memory limit: $MEMORY_LIMIT"
# ConfigMap values
echo "Config: $CONFIG_KEY"
# Secret values
echo "Secret: $SECRET_KEY"

Terminal window
# Add to beginning (takes precedence)
export PATH="/usr/local/bin:$PATH"
# Add to end
export PATH="$PATH:/usr/local/bin"
# Add multiple
export PATH="/opt/bin:/usr/local/bin:$PATH"
# Conditional addition
if [[ ":$PATH:" != *":/custom/bin:"* ]]; then
export PATH="/custom/bin:$PATH"
fi
Terminal window
# Find command location
which python
which -a python # All occurrences
whereis python # Binary, source, man pages
# Check if in PATH
command -v python # Returns path or empty
type python # Shows type

# Simple format (no export)
VAR1=value1
VAR2=value2
Terminal window
# Create custom.sh
sudo tee /etc/profile.d/custom.sh <<'EOF'
export CUSTOM_VAR="value"
export PATH="/opt/custom/bin:$PATH"
EOF
# Makes available to all users on login
Terminal window
# In service file
[Service]
Environment="VAR1=value1"
EnvironmentFile=/etc/myapp/env
ExecStart=/usr/bin/myapp
# Environment file format
# VAR=value
# Lines starting with # are comments

Terminal window
# 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=secret
.env
# Don't put secrets in version control
# .gitignore:
# Use .env files with loading mechanism
if [[ -f .env ]]; then
set -a
source .env
set +a
fi
# .env should contain:
# APP_KEY=xxxxx
# DATABASE_PASSWORD=xxxxx
# API_TOKEN=xxxxx

#!/usr/bin/env bash
# Debug environment
echo "=== Original Environment ==="
env | sort > /tmp/env_before
# Run command
"$@"
echo "=== New Environment ==="
env | sort > /tmp/env_after
# Compare
diff /tmp/env_before /tmp/env_after

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

Continue to the next chapter to learn about Shell Expansion.


Previous Chapter: Job Control Next Chapter: Shell Expansion