Environment Variables

Expected level: Working

Environment variables are named string values that the operating system passes to every process it starts. Programs read them to learn about their surroundings and to get configuration that should not be written into the code.

Reading and setting them

# PowerShell
$env:API_URL                       # read
$env:API_URL = "http://localhost:5000"   # set for this session only
[Environment]::SetEnvironmentVariable("API_URL", "http://localhost:5000", "User")   # persist for your user
# Bash
echo "$API_URL"                    # read
export API_URL=http://localhost:5000     # set for this shell and its child processes
printenv                           # list all

In Command Prompt use echo %API_URL% and set API_URL=....

Things that surprise people

  • A variable set in a shell lasts only for that session and its child processes. On Windows, persistent ones live at User or Machine level (System Properties, Environment Variables). On Linux, persistent ones are exported from files such as ~/.bashrc or ~/.profile.
  • A running program does not see changes. After you change a persistent variable, restart the terminal, and the editor or IDE that was started from it.
  • Values are always strings. Convert numbers and booleans in your code ("false" is a non-empty string).
  • Names are case-insensitive on Windows and case-sensitive on Linux.
  • Environment variables are not a secret store. They are visible to the process, its children and often in crash dumps and diagnostics. See Secrets Management.

Well-known variables

PATH is the list of folders searched for programs (separated by ; on Windows, : on Linux). HOME or USERPROFILE is your home folder, and TEMP or TMPDIR the temp folder.

In projects

  • Read configuration from the environment at startup, with sensible defaults for local development.
  • Use a .env file for local values that a tool loads for you, add it to .gitignore and commit a .env.example with fake values (see Ignoring and Excluding Files).
  • Document every variable the application needs.

Try it

Print PATH in your shell and split it into lines. Set a variable in one terminal, then check whether a second terminal can see it. Write a tiny script that prints a variable, and run it with the variable set and unset.

Common mistakes

  • Storing secrets in environment variables as if they were a secret store.
  • Expecting a running terminal or editor to pick up a changed variable.
  • Treating values as numbers or booleans, when `"false"` is a non-empty string.
  • Committing a `.env` file instead of a `.env.example` with fake values.

Check yourself

  • How long does a variable set with `export` in one terminal last, and who can see it?
  • Why do you need to restart your editor after changing a persistent variable?
  • What do you commit instead of your local `.env` file?

Related topics

Terms

Further reading