【问题标题】:Loading python envvars without using `source`在不使用`source`的情况下加载python envvars
【发布时间】:2019-10-19 00:56:02
【问题描述】:

我正在寻找在 django 应用程序中加载 envvars.sh 文件的解决方案。我宁愿在设置模块中执行此操作,并在其外部保留一个文件。这是我目前拥有的:

SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

def source_envvars(fname='envvars.sh'):
    """Equivalent of `$ source {fname}` with lines in the form of `export key=value`"""
    envvars = os.path.join(SITE_ROOT, fname)
    if not os.path.exists(envvars): return
    with open(fname, 'r') as f:
        for line in f:
            if line.startswith('export '):
                line = line.strip()
                key = line.split('=')[0].split()[1]
                value = line.split('=')[1].strip('"\'')
                os.environ[key] = value


if not os.environ.get('DB_HOST'): source_envvars()
# rest of settings.py file...

使用这种方法有什么缺点吗?我知道这不支持复杂的 bash 类型的导出,但我所拥有的只是以下形式的基本导出:

export DB_HOST=rds.amazon.com/12345

上述方法是否正确实例化了所有变量,或者它似乎遗漏了什么或以某种方式不安全?

【问题讨论】:

    标签: python django environment-variables


    【解决方案1】:

    您的实现只能处理固定格式。 shell 脚本可能包含条件语句和循环等,如果不通过 shell 实际获取它们,则无法正确处理它们。

    因此,一种更稳健的方法是使用subprocess.check_output 运行shell,使用. 获取envvars.shenv 命令输出环境变量,然后可以使用其输出来创建一个生成器表达式以更新os.environ

    os.environ.update(
        line.rstrip().split('=', 1)
        for line in subprocess.check_output(['sh', '-c', '. envvars.sh; env']).splitlines()
    )
    

    【讨论】:

    • 关于这个的两个问题。 (1) 为什么需要. envvars.sh; 而不仅仅是envvars.sh? (2)另外,为什么你需要-c这个命令?
    • 除此之外,为什么不只是做sh envvars.sh; env 工作?
    • 我使用-c 在一个shell 会话中运行多个命令,以便env 可以检索由shell 脚本设置的环境变量。运行sh envvars.sh; env 将不起作用,因为envvars.sh 将在其自己的shell 中执行,因此env 将无法访问该shell 中设置的环境变量。出于与上述相同的原因,我使用. 为当前 shell 获取脚本以避免产生单独的 shell。
    猜你喜欢
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    • 2017-03-04
    • 2023-03-04
    • 2021-05-26
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多