set environment variables by file using python

2019-05-14 01:46发布

问题:

I have a file contains set of environment variables .

env_script.env:

export a=hjk
export b=jkjk
export c=kjjhh
export i=jkkl
..........

I want set these environment variables by reading from file . how can i do this in python

Tried sample code:

pipe = subprocess.Popen([".%s;env", "/home/user/env_script.env"], stdout=subprocess.PIPE, shell=True)
output = pipe.communicate()[0]
env = dict((line.split("=", 1) for line in output.splitlines()))
os.environ.update(env)

Please give some suggestion

回答1:

You don't need to use subprocess.

Read lines and split environment variable name, value and assign it to os.environ:

import os

with open('/home/user/env_script.env') as f:
    for line in f:
        if 'export' not in line:
            continue
        if line.startswith('#'):
            continue
        # Remove leading `export `
        # then, split name / value pair
        key, value = line.replace('export ', '', 1).strip().split('=', 1)
        os.environ[key] = value

or using dict.update and generator expression:

with open('env_script.env') as f:
    os.environ.update(
        line.replace('export ', '', 1).strip().split('=', 1) for line in f
        if 'export' in line
    )

Alternatively, you can make a wrapper shell script, which sources the env_script.env, then execute the original python file.

#!/bin/bash
source /home/user/env_script.env
python /path/to/original_script.py


回答2:

Modern operating systems do not allow a child process to change the environment of its parent. The environment can only be changed for the current process and its descendants. And a Python interpreter is a child of the calling shell.

That's the reason why source is not an external command but is interpreted directly by the shell to allow a change in its environment.

It used to be possible in the good old MS/DOS system with the .COM executable format. A .com executable file had a preamble of 256 (0x100) bytes among which was a pointer to the COMMAND.COM's environment string! So with low level memory functions, and after ensuring not overwriting anything past the environment, a command could change directly its parent environment.

It may still be possible in modern OS, but require cooperation from system. For example Windows can allow a process to get read/write access to the memory of another process, provided the appropriate permissions are set. But this is really a hacky way, and I would not dare doing this in Python.

TL/DR: if your requirement is to change the environment of the calling shell from a Python script, you have misunderstood your requirement.


But what is easy is to start a new shell with a modified environment:

import os
import subprocess

env = os.environ.copy() # get a copy of current environment
# modify the copy of environment at will using for example falsetru's answer
# here is just an example
env['AAA'] = 'BBB'
# and open a subshell with the modified environment
p = subprocess.Popen("/bin/sh", env = env)
p.wait()