Start new subprocess with 'default' environment variables
Question: I'm writing a build script to resolve dependent shared libraries (and their
shared libraries, etc.). These shared libraries do not exist in the normal
`PATH` environment variable.

For the build process to work (for the compiler to find these libraries), the
`PATH` has been changed to include the directories of these libraries.

The build process is thus:

Loader script (changes PATH) -> Python-based build script -> Configure ->
Build -> Resolve Dependencies -> Install.

The Python instance inherits a changed `PATH` variable from its parent shell.

From within Python, I'm trying to get the default `PATH` (not the one
inherited from its parent shell).

The idea:

The idea to resolve the 'default' PATH variable is to somehow 'signal' the OS
to start a new process (running a script that prints PATH) but this process is
**NOT** a child of the current Python process (and presumably won't inherit
its modified environment variables).

The attempted implementation:

    
    
    import os
    import sys
    
    print os.environ["PATH"]
    print "---"
    os.spawnl(os.P_WAIT, sys.executable, "python", "-c \"import os;print(os.environ['PATH']);\"")
    

`os.spawn` appears to use the same environment variables as the Python process
which calls it. I've also tried this approach with `subprocess.POpen`, with no
success.

Can this approach be implemented ? If not, what is an alternative approach
(given that the loader script and the overall process can't change)?

I'm currently using Windows but the build script is to be cross-platform.

**EDIT:**

The cross-platform constraint appears to be too restrictive. Different
implementations of the same concept can now be considered.

As an example, using code from
[this](http://stackoverflow.com/a/1146404/2507539) answer, the Windows
registry can be used to get the 'default' system `PATH` variable.

    
    
    try:
        import _winreg as winreg
    except ImportError:
        try:
            import winreg
        except ImportError:
            winreg = None
    
    def env_keys(user=True):
        if user:
            root = winreg.HKEY_CURRENT_USER
            subkey = "Environment"
        else:
            root = winreg.HKEY_LOCAL_MACHINE
            subkey = r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
        return root, subkey
    
    def get_env(name, user=True):
        root, subkey = env_keys(user)
        key = winreg.OpenKey(root, subkey, 0, winreg.KEY_READ)
        try:
            value, _ = winreg.QueryValueEx(key, name)
        except WindowsError:
            return ""
        value = winreg.ExpandEnvironmentStrings(value)
        return value
    
    print get_env("PATH", False)
    

A consistent approach for *nix is needed.


Answer: Using `subprocess.Popen`, you can provide an environment for the child process
to use:

    
    
    default_path = os.environ['PATH'] # save the default path before changing it
    os.environ['PATH'] = # whatever you want
    child_env = os.environ.copy()
    child_env['PATH'] = default_path
    # change env
    subprocess.Popen(..., env=child_env)
    

The
[documentation](https://docs.python.org/2/library/subprocess.html#subprocess.Popen)
states that the provided environment will be used instead of inheriting it
from the parent:

> If env is not None, it must be a mapping that defines the environment
> variables for the new process; these are used instead of inheriting the
> current process’ environment, which is the default behavior.

