V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
lonelyparasol
V2EX  ›  Python

子进程如何重新读取系统环境变量, 而不只是继承了父级的环境变量?

  •  
  •   lonelyparasol · 2022-11-25 15:47:51 +08:00 · 3087 次点击
    这是一个创建于 721 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近遇到一个问题, 一个程序 A 使用 CreateProcess 和 ShellExecute 的方式调用另外一个程序 B 启动, 程序 B 启动后, 使用 GetEnvironmentVariable 读取到的环境变量只有程序 A 启动时从系统里加载的环境变量.

    有什么方法可以从系统中重新读取环境变量回来吗? 尝试过读取注册表, 但是一些用户没有权限去查, 限制比较多.

    14 条回复    2022-11-28 17:43:41 +08:00
    ysc3839
        1
    ysc3839  
       2022-11-25 15:57:16 +08:00
    lonelyparasol
        2
    lonelyparasol  
    OP
       2022-11-25 16:00:32 +08:00
    @ysc3839 看起来可以, 我去试试, 基于用户的 token 去重新获取, 感谢.
    JohnBull
        3
    JohnBull  
       2022-11-25 23:17:16 +08:00
    这完全违背了环境变量的设计初衷。
    你这是在强行用环境变量实现配置文件的功能。
    FrankHB
        4
    FrankHB  
       2022-11-26 06:27:34 +08:00
    @JohnBull 这哪来的设计初衷?又哪看出了 OP 要的是配置文件的功能?
    照你的说法是不是 Windows 系统属性里设置环境变量的界面也是违反初衷,该改用配置文件?
    (要是非得把注册表当配置文件,行吧,当我没说。)
    ysc3839
        5
    ysc3839  
       2022-11-26 20:36:47 +08:00 via Android
    @JohnBull 环境变量的设计初衷不就是子进程可以继承的配置文件吗?
    很多 Docker 镜像都是用环境变量来当配置文件的。
    JohnBull
        6
    JohnBull  
       2022-11-27 00:01:41 +08:00
    @ysc3839 环境变量的设计初衷恰恰是让子进程能够继承父进程的参数,而不是遵从全局的,形成一个配置一致的进程树。如果你想要跳过环境变量实现一个全局的配置,那当初就应该使用配置文件,或者设计相应的命令行参数。而不是思考如何加载爷爷进程的环境变量……不是说做不到,而是这种设计实在是太拧吧了

    通常,UNIX 应用程序历史悠久的配置原则是:

    代码写死的默认值 < 全局配置文件 < 进程环境变量 < 命令行参数

    对于同一个参数的值,采用后面覆盖前面的策略,清晰有效
    ysc3839
        7
    ysc3839  
       2022-11-27 00:54:22 +08:00 via Android
    @JohnBull #6 你说的这段话没问题,环境变量其中之一的作用确实是能让父进程覆盖子进程的参数。要跳过环境变量实现全局配置的话,确实是用配置文件更好。但是这跟 OP 的需求有什么关系呢? OP 这种需求显然就是不想跳过环境变量,想让子进程使用全局的环境变量。
    JohnBull
        8
    JohnBull  
       2022-11-27 16:11:31 +08:00
    @ysc3839 我在 6 楼提出来了:这种场合可以为这个配置项添加命令行参数,或者在 exec 子进程的时候删除特定环境变量,从而让配置文件 /默认值能够显现出来
    julyclyde
        9
    julyclyde  
       2022-11-27 16:48:20 +08:00
    并不存在“系统”环境变量这个概念
    环境变量都是进程级别的
    ysc3839
        10
    ysc3839  
       2022-11-27 20:24:00 +08:00 via Android
    @JohnBull 但是不是所有程序都接受命令行参数。比如我更新了 PATH ,然后启动一个 shell ,但是 shell 可不能通过命令行参数设置 PATH 。所以说到底 OP 的需求还是不能跳过环境变量,你扯这么多有用吗?
    @julyclyde Windows 有默认环境变量,是存在注册表中的。Unix 某种意义上也有默认环境变量,用空的环境变量跑一遍 profiles 等脚本,最终的环境变量结果也可以看作是默认环境变量。
    JohnBull
        11
    JohnBull  
       2022-11-27 22:16:13 +08:00
    @ysc3839 什么乱七八糟的啊。你究竟是子进程的开发者还是父进程的开发者?如果你是子进程的开发者,你就应该加上命令行参数或者干脆不采納环境变量而采纳配置文件甚至默认值;如果你是父进程的开发者,你就不应该在这时候设置环境变量。还不清楚吗?再说谁说 shell 不能设置环境变量的啊?
    julyclyde
        12
    julyclyde  
       2022-11-28 08:22:05 +08:00
    @ysc3839 是否接受命令行参数,也不影响“不存在‘系统’环境变量这个概念”的事实啊
    需要在已有规则下做事。颠覆规则的话需要重新做一套操作系统了,代价不合适的


    你的某种意义上的环境变量是依赖于进程启动的传承关系的。从交互式 shell 、登录 shell 启动,和从后台启动的情况都不一样,回头换个情况你又要遇到相同的问题。不要总是妄图从外围解决内部的问题
    lonelyparasol
        13
    lonelyparasol  
    OP
       2022-11-28 16:47:31 +08:00
    上面两位不要吵了, 我这个需求的初衷是有个程序 A 在一直执行的, 偶尔有新安装的软件会添加系统环境变量.
    程序 A 会根据用户需求, 创建进程或者线程去调用这些新安装的软件, 所以需要新创建的进程或线程自己的系统环境变量是最新的.
    使用窗口消息 WM_SETTINGCHANGE 和读取配置文件都有局限性, 我也是苦恼了好久.
    lonelyparasol
        14
    lonelyparasol  
    OP
       2022-11-28 17:43:41 +08:00
    用 CreateEnvironmentBlock 方式, 需要知道用户的帐号和密码, 也是有局限性.
    目前在尝试用 CMDB 设置计划任务, 看是否能重新加载系统的环境变量
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2828 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 04:06 · PVG 12:06 · LAX 20:06 · JFK 23:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.