Environment variable: definition and meaning
An environment variable is a named string value that a process receives from the process that started it. Programs read them for settings such as ports, URLs, and credentials, so the same code can behave differently on each machine.
What it is
Every process starts with an environment: a list of NAME=value strings handed to it by whatever launched it. Names and values are both strings. For the utilities it defines, POSIX limits names to uppercase letters, digits, and underscores, and a name cannot start with a digit, so DATABASE_URL is a normal name. Bash accepts letters, digits, and underscores and refuses to start a name with a digit, so export my-key=1 fails with a not a valid identifier error.
How child processes inherit them
On Linux, environ(7) says a child created with fork inherits a copy of its parent’s environment, and execve(2) lets the parent pass a different list on purpose. It is a copy, not a link. A child that changes a variable does not change its parent, and a parent that changes a variable later does not reach a child that is already running.
Shells add one more rule. A plain shell variable stays inside the shell until you export it, because export marks names to be passed to the commands you run afterwards. Putting NAME=value in front of a command sets it for that one command only.
FOO=plain
bash -c 'echo "[$FOO]"' # prints []
export FOO
bash -c 'echo "[$FOO]"' # prints [plain]
PORT=4000 node -e 'console.log(typeof process.env.PORT)' # prints stringThe last line is the usual trap in Node.js. process.env.PORT is the string "4000", so process.env.PORT === 4000 is false. Convert it with Number() before you compare.
Where it goes wrong
- Wrong launcher. A process inherits from whatever started it. An app started from an editor, a launcher, or a process manager gets that program’s environment, not the one in your open terminal tab. That is a common cause of “it works in my terminal”.
- Secrets travel. By default a child gets a copy of the whole environment, including variables it never needs. A key exported in a shell is visible to every program that shell launches afterwards, unless the launch passes a different environment.
- No live updates. Changing a variable in your shell or in a config file does nothing for processes that are already running. Restart them.
In Rig
- When Rig runs a Procfile command, the process environment comes from the project’s active env profile. The active profile is the lane’s profile, else the project’s own, else the global setting, else
local. - Profiles are plain files at
<project>/.rig/env/local.env,staging.env, andproduction.env. Rig creates a.rig/.gitignorecontainingenv/, so they stay out of Git by default. - When a port is set, Rig appends
--port Nto the Procfile command and exportsPORT,VITE_PORT,HOST_PORT, andnpm_config_port. - Secret-looking keys, such as those containing
pass,secret,token,key,auth, orcredential, are shown masked as ••••••••, and credentials or tokens inside other values are redacted. Agents get the same masking over MCP throughlist_env_profiles, andenv_diffreturns key names only.
See Env vars are masked.
Related terms
Sources
- POSIX Base Definitions: Environment Variables
- Linux man page: environ(7)
- Linux man page: execve(2)
- Node.js documentation: process.env
- GNU Bash Reference Manual: Definitions
- GNU Bash Reference Manual: Simple Command Expansion
- GNU Bash Reference Manual
- Rig documentation: Masked env manager (env profiles, masking, and port variables confirmed in Rig’s source code)
See how Rig fits in
Rig is a Mac app that starts, stops, and watches the processes in a project from one window. The knowledge base explains each part in plain language.