This guide serves as a comprehensive resource on Environment Variables, combining fundamental concepts, technical details, and DevOps strategies into a single structure.
1. Introduction: What Are Environment Variables?
Environment variables are system-wide key-value pairs that define the context in which a process runs. They act as a layer of configuration stored by the Operating System (OS) and passed to programs at runtime.
Instead of hard-coding values (like file paths, database URLs, or API keys) directly into source code, developers use environment variables to make applications dynamic and portable.
Structure
NAME=value
- Key: Usually uppercase (e.g.,
PATH,PORT). - Value: Strings, numbers, or paths (e.g.,
/usr/bin,3000).
2. Why Do They Exist?
The primary purpose of environment variables is to decouple configuration from application code. Without them, specific settings would need to be hard-coded into the source code, making the software brittle and insecure.
They solve four specific problems:
- Security: Storing sensitive data like API keys, database passwords, and auth tokens outside the codebase prevents them from being accidentally committed to version control (Git).
- Environment Switching: They allow the same code to behave differently in Development (using a local DB) versus Production (using a real DB) simply by changing a variable like
NODE_ENV. - System Configuration: They tell the Operating System where to find executables (via
PATH) or libraries without the user needing to type full file paths. - User Customization: They allow users to set personal preferences, such as their default text editor (
EDITOR=vim) or language (LANG=en_US), which programs then respect.
3. Setting, Unsetting, and Making Variables Permanent
How you interact with these variables depends on your operating system and whether you need the variable to last for a single session or persist forever.
Viewing Variables
- Linux/macOS:
printenvorenv: Lists all exported environment variables.echo $VARIABLE_NAME: Prints the value of a specific variable (e.g.,echo $HOME).
- Windows (Command Prompt):
set: Lists variables.echo %VARIABLE_NAME%: Prints a value.
- Windows (PowerShell):
Get-ChildItem Env:: Lists all variables.$Env:VARIABLE_NAME: Prints a value.
A. Temporary (Session Only)
These variables disappear as soon as you close the terminal window.
Linux & macOS (Bash/Zsh)
- Set:
export MY_VAR="Hello World" - Unset:
unset MY_VAR
Windows (CMD)
- Set:
set MY_VAR=Hello World - Unset:
set MY_VAR=(Setting it to empty removes it).
B. Permanent (Persists After Restart)
To keep variables across system restarts, they must be written to configuration files or system registries.
Linux & macOS (Terminal/Zsh)
Modern macOS uses the Zsh shell by default, while many Linux distributions use Bash. The logic is identical, but the file name differs.
- Identify your shell config file:
- For macOS (Zsh):
~/.zshrc - For Linux (Bash):
~/.bashrc
- For macOS (Zsh):
- Set Permanent: Open the file and append the export command.
echo 'export MY_VAR="Hello World"' >> ~/.zshrc - Apply Changes: Reload the configuration without restarting.
source ~/.zshrc - Unset Permanent: Open the file (
nano ~/.zshrc), delete the line containing the export, save, and runsource ~/.zshrc.
Windows
Windows has two layers: User (current user only) and System (all users). You can set these via Command Line or GUI.
- Using Command Line (setx):
setx MY_VAR "Hello World"Note:
setxwrites the variable permanently, but it will not appear in the current open window. You must open a new CMD window to see it. - Using GUI (Recommended for PATH):
- Search for "Edit the system environment variables" in the Start Menu.
- Click "Environment Variables".
- Click "New" to add or "Delete" to remove.
- Unset Permanent:
REG delete "HKCU\Environment" /F /V "MY_VAR"Or simply use the GUI to delete the entry.
iOS (Apple Mobile Development)
iOS is a closed mobile operating system; you do not set system-wide environment variables like you do on a computer. However, for development purposes, variables are handled in Xcode:
- Xcode Schemes: In Xcode, go to Product > Scheme > Edit Scheme. Under Run > Arguments, you can add Environment Variables that are injected into the App Sandbox when the app launches on the simulator or device.
- .xcconfig Files: For build-time configurations (like changing API endpoints between Debug and Release), developers use configuration files known as
.xcconfig.
4. Critical System Variables
Your OS relies on several built-in variables to function correctly.
| Variable | Purpose |
|---|---|
| PATH | List of directories where the OS looks for executable programs. |
| HOME (Linux/Mac) / USERPROFILE (Win) | The current user’s home directory. |
| USER (Linux/Mac) / USERNAME (Win) | The name of the current logged-in user. |
| SHELL | The path to the current shell (e.g., /bin/bash). |
| PWD | The Current Working Directory. |
| LANG | Defines the system language and character encoding. |
5. Deep Dive: The $PATH Variable
The most important variable for daily usage is PATH. It is a list of directories separated by colons (:) on Unix or semicolons (;) on Windows.
Example Value:
/usr/local/sbin:/usr/local/bin:/usr/bin:/bin
How Command Resolution Works
When you type a command like ls or python:
- The shell checks for Aliases.
- The shell checks for Built-ins (commands built into the shell itself).
- The shell searches the directories listed in
$PATHfrom left to right. - It executes the first match it finds.
- If no match is found, it returns
command not found.
Modifying PATH
- Wrong (Overwriting):
export PATH=/my/custom/bin(This breaks standard commands). - Correct (Appending):
export PATH=$PATH:/my/custom/bin(Adds to the end). - Correct (Prepending):
export PATH=/my/custom/bin:$PATH(Adds to the start, giving priority).
6. System Architecture: How Variables "Flow"
The Process Tree (Inheritance)
In Unix/Linux systems, processes are created using two system calls:
fork(): Creates a copy of the current process.exec(): Replaces the copy with a new program.
The Rule of Inheritance: When a parent process creates a child process, the child receives a copy of the parent's environment variables. However, a child process cannot modify the parent's environment.
Runtime vs. Execution Environment
- Runtime Environment: The OS-level state provided to the process (Env Vars, User permissions, Memory limits).
- Execution Environment: The context of the language or framework (Node.js runtime, dependencies, virtual environments).
7. Configuration Files: Where Variables Live (Linux/macOS)
Variables set in the terminal are temporary. To make them permanent, they must be written to specific files.
The File Hierarchy
- System-Wide (Global):
/etc/environment: Highest level. Simple key=value pairs./etc/profile: Loaded for login shells.
- User-Specific (Local):
~/.bash_profileor~/.zprofile: Loaded for Login Shells (SSH, GUI login).~/.bashrcor~/.zshrc: Loaded for Non-Login Shells (opening a terminal tab).
8. Shell Scripting Special Variables
When writing scripts, the shell provides "automatic" variables that act like environment variables but hold metadata about the execution.
| Variable | Description |
|---|---|
$0 |
The name of the script or command currently running. |
$1, $2 |
The arguments passed to the script. |
$# |
The number of arguments passed. |
$@ |
A list of all arguments passed. |
$? |
The exit status of the last command (0 = Success). |
$$ |
The Process ID (PID) of the current shell. |
9. Environment Variables in Modern DevOps
1. .env Files
Developers use files named .env to store local secrets and config. Tools like dotenv load these automatically.
PORT=3000
DB_HOST=localhost
API_KEY=12345
2. Docker: Build vs. Runtime
- ARG (Build-time): Available only while the image builds.
- ENV (Runtime): Persists inside the container when it runs.
docker run -e PORT=8080 -e NODE_ENV=production my-app
3. Kubernetes
- ConfigMaps: For non-sensitive data (e.g.,
THEME=blue). - Secrets: For sensitive data (e.g.,
DB_PASS), encoded and injected safely.
10. Security and Modern Best Practices
- Expansion: You can define variables using other variables:
LOG_DIR=$BASE_DIR/logs. - Secrets: Never hard-code API keys. Inject them via environment variables.
- Logging: Do not print the entire environment in logs to avoid leaking secrets.
- Git: Never commit
.envfiles to version control. Add them to.gitignore.
Comments
Post a Comment