ZetCode

Python os.putenv Function

Last modified April 11, 2025

This comprehensive guide explores Python's os.putenv function, which modifies environment variables. We'll cover environment basics, process inheritance, and practical configuration examples.

Basic Definitions

The os.putenv function sets environment variables in the current process. It modifies the process environment that child processes will inherit.

Key parameters: name (variable name), value (variable content). Returns None. Changes may not reflect in os.environ dictionary immediately.

Setting a Basic Environment Variable

The simplest use of os.putenv creates a new environment variable. This example demonstrates setting and verifying a variable.

basic_set.py
import os

# Set a new environment variable
os.putenv("MY_VARIABLE", "test_value")

# Note: os.putenv doesn't update os.environ automatically
print("Through os.putenv:")
print(os.getenv("MY_VARIABLE"))  # May or may not show the value

# Alternative using os.environ
os.environ["MY_VARIABLE"] = "test_value"
print("\nThrough os.environ:")
print(os.getenv("MY_VARIABLE"))  # Will definitely show the value

This example shows the difference between os.putenv and os.environ. The latter is generally preferred as it maintains consistency with Python's environment.

The os.putenv function directly calls the C library putenv function, which has platform-specific behaviors.

Modifying PATH Environment Variable

The PATH variable controls where the system looks for executables. This example demonstrates how to safely modify it using os.putenv.

modify_path.py
import os

# Get current PATH
current_path = os.getenv("PATH", "")
print(f"Current PATH: {current_path[:50]}...")

# Add a new directory to PATH
new_path = "/usr/local/myapp/bin"
updated_path = f"{current_path}:{new_path}" if current_path else new_path

# Update the environment
os.putenv("PATH", updated_path)

# Verify in a child process
os.system('echo "New PATH in child process: $PATH"')

# Note: Parent process PATH remains unchanged
print(f"Parent process PATH still: {os.getenv('PATH')[:50]}...")

This shows how PATH modifications affect child processes but not the current Python process. The change becomes visible in spawned subprocesses.

For current process PATH modifications, use os.environ directly instead.

Platform-Specific Behavior

os.putenv behaves differently across operating systems. This example demonstrates Windows vs Unix differences in environment handling.

platform_diff.py
import os
import platform

# Set variables differently based on platform
if platform.system() == "Windows":
    var_name = "TEMP"
    var_value = "C:\\Temp"
else:
    var_name = "TMPDIR"
    var_value = "/tmp"

os.putenv(var_name, var_value)

# Check if the variable is set
print(f"Checking {var_name}:")
print(f"os.getenv: {os.getenv(var_name)}")
print(f"os.environ.get: {os.environ.get(var_name)}")

# Spawn a child process to verify
if platform.system() == "Windows":
    os.system('echo %TEMP%')
else:
    os.system('echo $TMPDIR')

Windows and Unix handle environment variables differently. Windows variables are case-insensitive while Unix variables are case-sensitive.

The example shows how to write platform-aware code when working with environment variables.

Unsetting Environment Variables

To remove an environment variable, set its value to an empty string or None. This example demonstrates both approaches.

unset_var.py
import os

# Set a test variable
os.putenv("TEST_VAR", "value")
print(f"Before unset: {os.getenv('TEST_VAR')}")

# Method 1: Set to empty string
os.putenv("TEST_VAR", "")
print(f"After empty string: {os.getenv('TEST_VAR')}")

# Method 2: On Unix-like systems, use None equivalent
os.unsetenv("TEST_VAR")  # Better alternative
print(f"After unsetenv: {os.getenv('TEST_VAR')}")

# Spawn child to verify
os.system('echo "In child: $TEST_VAR"')

The example shows different ways to remove environment variables. The os.unsetenv function is preferred for clarity and cross-platform use.

Note that unset variables return None from os.getenv, while empty variables return empty strings.

Environment Variable Inheritance

Child processes inherit environment variables from their parent. This example demonstrates how changes propagate to subprocesses.

inheritance.py
import os
import subprocess

# Set a variable
os.putenv("PARENT_VAR", "parent_value")

# Spawn a child process
print("Child process output:")
subprocess.run(['python3', '-c', 'import os; print(os.getenv("PARENT_VAR"))'])

# Modify in child (doesn't affect parent)
print("\nModified in child:")
subprocess.run(['python3', '-c', 'import os; os.putenv("CHILD_VAR", "child_value"); print(os.getenv("CHILD_VAR"))'])

# Check if child var exists in parent
print(f"\nParent checking CHILD_VAR: {os.getenv('CHILD_VAR')}")

Environment changes flow downward to child processes but not upward to parents. Each process maintains its own independent environment.

This demonstrates the one-way nature of environment variable inheritance in process hierarchies.

Security Considerations

Environment variables can expose sensitive data. This example shows secure handling practices with os.putenv.

security.py
import os
import getpass

# Unsafe practice - putting sensitive data in environment
password = getpass.getpass("Enter password (will be stored unsafely): ")
os.putenv("DB_PASSWORD", password)  # UNSAFE

# Better approach - use command-line arguments or pipes
print("\nSecure alternative:")
print("Pass sensitive data through pipes or temporary files")

# Clean up (doesn't guarantee memory safety)
os.unsetenv("DB_PASSWORD")

# Check if cleaned up
print(f"Password still in env: {os.getenv('DB_PASSWORD') is not None}")

The example demonstrates why sensitive data shouldn't be stored in environment variables. Child processes and system tools may access these values.

For security, prefer other mechanisms like pipes, sockets, or secure memory for sensitive data transfer.

Security Considerations

Best Practices

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.