我有一个包含一组环境变量的文件。
env_script.env:
export a=hjk
export b=jkjk
export c=kjjhh
export i=jkkl
..........
我想通过从文件中读取来设置这些环境变量。 我怎么能在python中做到这一点
尝试过示例代码:
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)
请提出一些建议
答案 0 :(得分:5)
您不需要使用子流程。
读取行并拆分环境变量名称,值并将其分配给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
或使用dict.update
和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
)
或者,您可以创建一个包装器shell脚本,source
是env_script.env
,然后执行原始的python文件。
#!/bin/bash
source /home/user/env_script.env
python /path/to/original_script.py
答案 1 :(得分:0)
现代操作系统不允许子进程更改其父进程的环境。只能为当前进程及其后代更改环境。 Python解释器是调用shell的子代。
这就是为什么source
不是外部命令而是由shell直接解释以允许其环境发生变化的原因。
过去可以在旧的MS / DOS系统中使用.COM可执行格式。一个.com可执行文件的前导码为256(0x100)字节,其中有一个指向COMMAND.COM环境字符串的指针!因此,对于低级别的内存函数,并且在确保不覆盖环境之外的任何内容之后,命令可以直接更改其父环境。
在现代操作系统中仍有可能,但需要系统的合作。例如,如果设置了适当的权限,Windows可以允许进程获得对另一个进程的内存的读/写访问权限。但这真的是一种hacky方式,我不敢用Python做这件事。
TL / DR:如果您的要求是从Python脚本更改调用 shell的环境,则您误解了您的要求。
但是,使用修改后的环境启动新shell很容易:
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()
答案 2 :(得分:0)
有一个很棒的python库python-dotenv,可让您将变量从.env
文件或任何您想要的文件导出到您的环境:
# to install
pip install -U python-dotenv
# your .env file
export a=hjk
export b=jkjk
export c=kjjhh
export i=jkkl
...
开始时,您只需将其加载到python中即可
# settings.py
from dotenv import load_dotenv
load_dotenv()