Skip to content
AgileLogics
5 min read

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, and PATH changes.
  • ~/.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.