Environment Variables: Setting and Exporting in Linux/Unix

Master environment variables in Linux/Unix systems. Learn to set, export, and manage variables for configuration, security, and system customization.

Environment Variables: Setting and Exporting in Linux/Unix Systems

Introduction

Environment variables are dynamic named values that can affect the way running processes behave on a computer. They are part of the environment in which a process runs and can be used to pass configuration information to applications, store system-wide settings, and customize the behavior of the shell and other programs.

This comprehensive guide covers the concepts, methods, and best practices for setting and exporting environment variables in Linux and Unix-like systems.

What are Environment Variables?

Environment variables are key-value pairs that are available system-wide and can be accessed by any process running on the system. They serve several important purposes:

- Configuration Storage: Store configuration data that applications can read - System Information: Provide information about the system environment - Path Management: Define where the system should look for executable files - User Preferences: Store user-specific settings and preferences - Security: Store sensitive information like API keys and credentials

Types of Variables

There are two main types of variables in shell environments:

1. Shell Variables: Available only to the current shell session 2. Environment Variables: Available to the current shell and all child processes

Basic Concepts and Terminology

Variable Scope

Variables can have different scopes depending on how they are defined:

| Scope Type | Description | Visibility | Persistence | |------------|-------------|------------|-------------| | Local | Defined within a function or script | Current function/script only | Until function/script ends | | Shell | Defined in current shell session | Current shell only | Until shell session ends | | Environment | Exported variables | Current shell and child processes | Until shell session ends | | Global | System-wide variables | All users and processes | Persistent across reboots |

Variable Naming Conventions

Environment variables follow specific naming conventions:

- Use uppercase letters for environment variables - Use underscores to separate words - Start with a letter or underscore - Contain only letters, numbers, and underscores - Avoid spaces and special characters

Examples of valid variable names: - PATH - HOME - USER_PREFERENCES - DB_CONNECTION_STRING - _PRIVATE_VAR

Setting Environment Variables

Method 1: Direct Assignment

The most basic way to set a variable is through direct assignment:

`bash VARIABLE_NAME=value `

Example: `bash MY_APP_CONFIG=/etc/myapp/config.conf DATABASE_URL=postgresql://localhost:5432/mydb `

Notes: - No spaces around the equals sign - Values with spaces must be quoted - This creates a shell variable, not an environment variable

Method 2: Using the export Command

To make a variable available to child processes, use the export command:

`bash export VARIABLE_NAME=value `

Example: `bash export PATH=/usr/local/bin:$PATH export JAVA_HOME=/usr/lib/jvm/java-11-openjdk `

Method 3: Two-Step Process

You can also set a variable and then export it separately:

`bash VARIABLE_NAME=value export VARIABLE_NAME `

Example: `bash API_KEY=abc123def456 export API_KEY `

Viewing Environment Variables

Command: env

The env command displays all environment variables:

`bash env `

Output example: ` PATH=/usr/local/bin:/usr/bin:/bin HOME=/home/username USER=username SHELL=/bin/bash `

Command: printenv

Similar to env, but with additional options:

`bash printenv printenv VARIABLE_NAME `

Examples: `bash

Display all environment variables

printenv

Display specific variable

printenv PATH

Display multiple specific variables

printenv PATH HOME USER `

Command: echo

Display the value of a specific variable:

`bash echo $VARIABLE_NAME `

Examples: `bash echo $PATH echo $HOME echo $USER `

Command: set

Display all variables (both shell and environment):

`bash set `

Note: This command shows more output than env because it includes shell variables and functions.

Common Environment Variables

System Variables

| Variable | Description | Example Value | |----------|-------------|---------------| | PATH | Directories to search for executables | /usr/local/bin:/usr/bin:/bin | | HOME | User's home directory | /home/username | | USER | Current username | john | | SHELL | Default shell | /bin/bash | | PWD | Present working directory | /home/user/documents | | OLDPWD | Previous working directory | /home/user | | TERM | Terminal type | xterm-256color | | LANG | System language | en_US.UTF-8 |

Application-Specific Variables

| Variable | Description | Example Value | |----------|-------------|---------------| | JAVA_HOME | Java installation directory | /usr/lib/jvm/java-11-openjdk | | PYTHONPATH | Python module search path | /usr/local/lib/python3.8/site-packages | | NODE_ENV | Node.js environment | production | | DATABASE_URL | Database connection string | postgresql://user:pass@localhost/db | | API_KEY | API authentication key | sk-1234567890abcdef |

Persistent Environment Variables

User-Level Persistence

To make environment variables persistent for a specific user, add them to shell configuration files:

#### Bash Configuration Files

| File | Purpose | When Loaded | |------|---------|-------------| | ~/.bashrc | Interactive non-login shells | Every new terminal | | ~/.bash_profile | Login shells | Login only | | ~/.profile | POSIX-compliant login shells | Login (all shells) | | ~/.bash_login | Bash login shells | Login (if no .bash_profile) |

Example ~/.bashrc: `bash

Custom environment variables

export EDITOR=vim export BROWSER=firefox export JAVA_HOME=/usr/lib/jvm/java-11-openjdk export PATH=$PATH:$HOME/bin:$HOME/.local/bin

Application-specific variables

export NODE_ENV=development export DATABASE_URL=postgresql://localhost:5432/myapp `

#### Zsh Configuration

For Zsh users, use ~/.zshrc:

`bash

~/.zshrc

export EDITOR=vim export PATH=$PATH:$HOME/bin export PYTHONPATH=$PYTHONPATH:$HOME/python-libs `

System-Level Persistence

For system-wide environment variables, modify these files:

#### /etc/environment

Simple key-value pairs (Ubuntu/Debian):

`bash PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" JAVA_HOME="/usr/lib/jvm/java-11-openjdk" EDITOR="vim" `

Notes: - No export keyword needed - Values must be quoted - No variable expansion

#### /etc/profile

System-wide profile for all users:

`bash

/etc/profile

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk export PATH=$PATH:$JAVA_HOME/bin export EDITOR=vim `

#### /etc/bash.bashrc

System-wide bashrc:

`bash

/etc/bash.bashrc

export HISTSIZE=10000 export HISTFILESIZE=20000 export EDITOR=vim `

Advanced Techniques

Variable Expansion and Substitution

#### Basic Expansion `bash export PATH=$PATH:/new/directory export FULL_NAME="$FIRST_NAME $LAST_NAME" `

#### Parameter Expansion

| Syntax | Description | Example | |--------|-------------|---------| | ${VAR} | Basic expansion | ${HOME}/documents | | ${VAR:-default} | Use default if unset | ${PORT:-8080} | | ${VAR:=default} | Set default if unset | ${CONFIG:=/etc/app.conf} | | ${VAR:+alternate} | Use alternate if set | ${DEBUG:+--verbose} | | ${VAR:?error} | Error if unset | ${REQUIRED:?Variable required} |

Examples: `bash

Set default port if not specified

export PORT=${PORT:-3000}

Set configuration file with default

export CONFIG_FILE=${CONFIG_FILE:=/etc/myapp/config.json}

Add debug flag if DEBUG is set

COMMAND="myapp ${DEBUG:+--debug} --config $CONFIG_FILE" `

Conditional Variable Setting

`bash

Set variable only if not already set

if [ -z "$JAVA_HOME" ]; then export JAVA_HOME=/usr/lib/jvm/default-java fi

Set variable based on system type

if [ "$(uname)" = "Darwin" ]; then export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home else export JAVA_HOME=/usr/lib/jvm/java-11-openjdk fi `

Array Variables

Bash supports array variables:

`bash

Declare array

declare -a SERVERS=("web1.example.com" "web2.example.com" "web3.example.com")

Export array (as string)

export SERVER_LIST="${SERVERS[*]}"

Access array elements

echo "First server: ${SERVERS[0]}" echo "All servers: ${SERVERS[@]}" `

Environment Variables in Different Contexts

Shell Scripts

When using environment variables in shell scripts:

`bash #!/bin/bash

Check if required variables are set

if [ -z "$DATABASE_URL" ]; then echo "Error: DATABASE_URL environment variable is required" exit 1 fi

Use variables with defaults

LOG_LEVEL=${LOG_LEVEL:-INFO} PORT=${PORT:-8080}

Export variables for child processes

export APP_ENV=production export LOG_FILE=/var/log/myapp.log

Run application with environment

exec myapp --port "$PORT" --log-level "$LOG_LEVEL" `

Process Substitution

Environment variables can be set for specific commands:

`bash

Set variable for single command

ENV_VAR=value command

Multiple variables for single command

VAR1=value1 VAR2=value2 command

Examples

DEBUG=1 node app.js PORT=3000 npm start RAILS_ENV=production bundle exec rails server `

Subprocess Environment

`bash

Create clean environment

env -i command

Run with specific environment

env VAR1=value1 VAR2=value2 command

Remove specific variables

env -u UNWANTED_VAR command `

Security Considerations

Sensitive Information

Best Practices: - Never store passwords or API keys in shell history - Use secure methods to pass sensitive variables - Limit access to configuration files containing secrets - Use tools like direnv or secret management systems

Example secure variable setting: `bash

Read password securely

read -s -p "Enter database password: " DB_PASSWORD export DB_PASSWORD

Or use a secure file

export DB_PASSWORD=$(cat /secure/path/db_password) `

Variable Validation

`bash

Validate required variables

validate_env() { local required_vars=("DATABASE_URL" "API_KEY" "SECRET_KEY") local missing_vars=() for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then missing_vars+=("$var") fi done if [ ${#missing_vars[@]} -ne 0 ]; then echo "Error: Missing required environment variables: ${missing_vars[*]}" return 1 fi }

Call validation function

validate_env || exit 1 `

Troubleshooting Common Issues

Issue 1: Variables Not Available in Child Processes

Problem: Variable set but not accessible in subshells or child processes.

Solution: Use export to make variables available to child processes: `bash

Wrong

MY_VAR=value

Correct

export MY_VAR=value `

Issue 2: Variables Not Persisting

Problem: Variables disappear when terminal is closed.

Solution: Add variables to appropriate configuration files: `bash

Add to ~/.bashrc or ~/.profile

echo 'export MY_VAR=value' >> ~/.bashrc source ~/.bashrc `

Issue 3: Path Issues

Problem: Commands not found after modifying PATH.

Solution: Verify PATH syntax and order: `bash

Check current PATH

echo $PATH

Correct way to add to PATH

export PATH=/new/directory:$PATH

Verify the change

which command_name `

Issue 4: Variable Expansion Issues

Problem: Variables not expanding correctly.

Solutions: `bash

Use quotes for variables with spaces

export MY_PATH="$HOME/My Documents"

Use braces for clarity

export FULL_PATH="${HOME}/bin:${PATH}"

Debug variable expansion

set -x # Enable debug mode echo $MY_VAR set +x # Disable debug mode `

Best Practices

Naming Conventions

- Use descriptive, uppercase names for environment variables - Group related variables with common prefixes - Follow application-specific conventions

Examples: `bash

Good naming

export DB_HOST=localhost export DB_PORT=5432 export DB_NAME=myapp export DB_USER=appuser

Application-specific grouping

export MYAPP_CONFIG_DIR=/etc/myapp export MYAPP_LOG_LEVEL=INFO export MYAPP_DEBUG_MODE=false `

Documentation

Document environment variables in your projects:

`bash

Create .env.example file

DB_HOST=localhost DB_PORT=5432 DB_NAME=example_db API_KEY=your_api_key_here DEBUG=false `

Configuration Management

Use configuration management tools for complex environments:

- direnv: Automatically load environment variables based on directory - dotenv: Load environment variables from .env files - Docker: Use environment variables in containers - Kubernetes: ConfigMaps and Secrets

Example with direnv: `bash

.envrc file

export DATABASE_URL=postgresql://localhost:5432/myapp export API_KEY=development_key export DEBUG=true

Allow the .envrc file

direnv allow `

Practical Examples

Web Development Environment

`bash

~/.bashrc

export NODE_ENV=development export PORT=3000 export DATABASE_URL=postgresql://localhost:5432/webapp export REDIS_URL=redis://localhost:6379 export JWT_SECRET=development_secret export API_BASE_URL=http://localhost:3000/api `

Java Development Environment

`bash

~/.profile

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk export MAVEN_HOME=/opt/maven export GRADLE_HOME=/opt/gradle export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin:$GRADLE_HOME/bin export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m" `

Python Development Environment

`bash

~/.bashrc

export PYTHONPATH=$PYTHONPATH:$HOME/python-projects export VIRTUAL_ENV_DISABLE_PROMPT=1 export PIP_REQUIRE_VIRTUALENV=true export PYTHONDONTWRITEBYTECODE=1 `

DevOps Environment

`bash

~/.profile

export KUBECONFIG=$HOME/.kube/config export TERRAFORM_LOG=INFO export AWS_DEFAULT_REGION=us-west-2 export DOCKER_BUILDKIT=1 export COMPOSE_DOCKER_CLI_BUILD=1 `

Conclusion

Environment variables are a fundamental concept in Unix-like systems that provide a flexible way to configure applications and system behavior. Understanding how to properly set, export, and manage environment variables is crucial for system administration, software development, and automation tasks.

Key takeaways: - Use export to make variables available to child processes - Choose appropriate configuration files for persistence - Follow naming conventions and security best practices - Document your environment variables for team collaboration - Use tools and frameworks to manage complex configurations

By mastering environment variables, you can create more flexible, configurable, and maintainable systems and applications.

Tags

  • Linux
  • Unix
  • bash
  • shell-scripting
  • system-administration

Related Articles

Popular Technical Articles & Tutorials

Explore our comprehensive collection of technical articles, programming tutorials, and IT guides written by industry experts:

Browse all 8+ technical articles | Read our IT blog

Environment Variables: Setting and Exporting in Linux/Unix