在Django settings.py中调用envvars.sh导入环境变量失败,求解决方案
这个问题我之前也碰到过!你用subprocess.call(['source', 'envvars.sh'])的思路其实有个关键误区——subprocess启动的是子shell进程,它里面加载的环境变量根本不会传递回你的Python父进程,所以不管你在子shell里source多少次,Python进程的os.environ里还是拿不到那些变量。而且source是shell内置命令,默认subprocess不会启动shell来执行它,这也是之前代码无效的原因之一。
下面给你几个可行的实现方法:
方法一:启动Django前先加载环境变量
最简单的方式是在启动Django进程的命令前先source脚本,让父shell先加载变量,再启动Python。比如在终端执行:source envvars.sh && python manage.py runserver如果你用虚拟环境,可以把
source /path/to/envvars.sh加到虚拟环境的activate脚本末尾,这样每次激活环境时自动加载变量,之后启动Django就不用每次手动source了。方法二:手动解析envvars.sh文件
写一个Python函数直接读取并解析shell脚本里的环境变量赋值,把它们加到os.environ中。这种方法不需要依赖外部工具,适合处理简单的变量定义(比如export DB_PASSWORD=xxx这类格式)。示例代码如下:import os def load_shell_env(env_file_path): with open(env_file_path, 'r') as f: for line in f: line = line.strip() # 跳过注释、空行和非赋值语句 if not line or line.startswith('#') or '=' not in line: continue # 去掉开头的export关键字(如果有的话) if line.startswith('export '): line = line[7:] # 拆分变量名和值(只按第一个=拆分,避免值里包含=的情况) var_name, var_value = line.split('=', 1) # 去掉值两端可能的引号(单引号或双引号) var_value = var_value.strip('\'"') # 把变量加入环境变量 os.environ[var_name] = var_value # 在settings.py开头调用这个函数 load_shell_env('envvars.sh') # 之后就可以正常获取变量了 DB_PASSWORD = os.environ.get('DB_PASSWORD', '')注意:这个方法只处理简单的静态赋值,如果你的
envvars.sh里有复杂的shell逻辑(比如变量替换、命令输出赋值),可能需要更复杂的解析逻辑,或者换用其他方法。方法三:使用python-dotenv库(推荐)
这是Django项目中管理环境变量的常用方案,比手动解析shell脚本更优雅。你可以把环境变量整理成.env文件(格式类似envvars.sh,但不需要export关键字,每行VAR=value),然后用python-dotenv库加载:- 先安装库:
pip install python-dotenv - 在settings.py开头添加:
from dotenv import load_dotenv import os # 加载.env文件 load_dotenv() # 默认加载当前目录下的.env文件,如果你的文件是envvars.sh,可以指定路径:load_dotenv('envvars.sh') # 获取环境变量 DB_PASSWORD = os.environ.get('DB_PASSWORD', '')
这个库会自动处理带
export的行,也支持简单的变量替换,非常适合管理项目的配置变量。- 先安装库:
内容的提问来源于stack exchange,提问作者FI-Info

