env_loader.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334
  1. """
  2. conf/env.sh 跨语言单源 bootstrap。
  3. 用法:在 dw_base/__init__.py 顶部调用一次,之后 Python 侧通过 os.environ[X] 读取。
  4. 实现:让 bash 自己解析 env.sh(`bash -c '. env.sh && env -0'`),避免重写解析器导致 bash/python 双解析漂移。
  5. """
  6. import os
  7. import subprocess
  8. from pathlib import Path
  9. def bootstrap_env(env_sh_path: str = None) -> bool:
  10. """source env.sh 注入环境变量;返回是否加载成功。
  11. env.sh 不存在时返回 False 静默跳过——Spark executor 上 dw_base 以 zip 分发、不含 conf/,
  12. 此时不加载项目 env,由 dw_base/__init__ 跳过 driver 专属初始化(见该文件 guard)。
  13. env.sh 存在但 source 失败(语法错等)仍按 check=True 抛出,driver 上大声失败。
  14. """
  15. if env_sh_path is None:
  16. project_root = Path(__file__).resolve().parents[2]
  17. env_sh_path = str(project_root / 'conf' / 'env.sh')
  18. if not os.path.isfile(env_sh_path):
  19. return False
  20. result = subprocess.run(
  21. ['bash', '-c', f'. "{env_sh_path}" && env -0'],
  22. stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True,
  23. )
  24. for entry in result.stdout.split(b'\x00'):
  25. if not entry:
  26. continue
  27. key, _, value = entry.decode().partition('=')
  28. # setdefault: 若 shell 侧已 export(如 init.sh 已 source env.sh),保留 shell 值不覆盖
  29. os.environ.setdefault(key, value)
  30. return True