Environment Variables and Configuration
Prerequisites: Variables, Script arguments
Environment variables are passed from a process to the programs it starts. They're how the shell tells programs about your settings — and how scripts receive configuration.
Shell variables vs environment variables
A normal variable exists only in the current shell. export makes it an
environment variable, visible to child processes:
greeting="hello"
bash -c 'echo "child sees: [$greeting]"'
export greeting
bash -c 'echo "child sees: [$greeting]"'
child sees: []
child sees: [hello]
Setting a variable for one command
show() { bash -c 'echo "APP_ENV=$APP_ENV LOG_LEVEL=$LOG_LEVEL"'; }
APP_ENV=production LOG_LEVEL=warn bash -c 'echo "APP_ENV=$APP_ENV LOG_LEVEL=$LOG_LEVEL"'
echo "afterwards: [${APP_ENV:-unset}]"
APP_ENV=production LOG_LEVEL=warn
afterwards: [unset]
NAME=value command sets the variable only for that command — a
clean way to configure a program without affecting anything else.
Configuring scripts with environment variables
cat > deploy.sh <<'EOF'
: "${DEPLOY_ENV:=staging}"
: "${API_TOKEN:?API_TOKEN must be set}"
echo "Deploying to $DEPLOY_ENV"
EOF
bash deploy.sh
echo "exit code: $?"
API_TOKEN=secret bash deploy.sh
DEPLOY_ENV=production API_TOKEN=secret bash deploy.sh
deploy.sh: line 2: API_TOKEN: API_TOKEN must be set
exit code: 1
Deploying to staging
Deploying to production
: "${VAR:=default}"sets a default (:is a command that does nothing, used here just to trigger the expansion).: "${VAR:?message}"stops the script if a required variable is missing.
Shell startup files
~/.bashrc— runs for each new interactive shell: aliases, functions, prompt, andPATHchanges.~/.bash_profile(or~/.profile) — runs for login shells; it usually just loads~/.bashrc.
# illustrative
# In ~/.bashrc
export PATH="$HOME/.local/bin:$PATH"
export EDITOR=vim
alias ll='ls -lah'
alias gs='git status'
Run source ~/.bashrc to apply changes to the current shell.
.env files
Many projects keep settings in a .env file. A script can load it:
printf 'DB_HOST=localhost\nDB_PORT=5432\n' > .env
set -a
source .env
set +a
echo "Connecting to $DB_HOST:$DB_PORT"
Connecting to localhost:5432
set -a exports every variable defined while it's on. Never commit
.env files containing secrets — add them to .gitignore.