【问题标题】:Correct way to reset Python's os.environ to the default values of a command shell将 Python 的 os.environ 重置为命令 shell 的默认值的正确方法
【发布时间】:2013-11-04 00:16:18
【问题描述】:

将 os.environ 重置为可以在命令 shell 中找到的默认值的 Python 方法是什么?我可以通过首先将 os.environ 推送到默认字典中来处理这个问题,但是如果 os.environ 在导入我的模块之前被另一个模块更改,该方法将失败。

在 Windows 中,我目前可以像这样重置值:

import os, subprocess, tempfile

def is_locked(filepath):
    ''' Needed to determine when the set command below completes
    '''
    locked = None
    file_object = None
    if os.path.exists(filepath):
        try:
            buffer_size = 8
            file_object = open(filepath, 'a', buffer_size)
            if file_object:
                locked = False
        except IOError, message:
            locked = True
        finally:
            if file_object:
                file_object.close()
    else:
        locked = True
    return locked

# Define a Windows command which would dump default env variables into a tempfile
#
# - start /i will give default cmd.exe environment variable to what follows.
#   It's the only way i found to get cmd.exe's default env variables and because
#   start terminates immediately i need to use is_locked defined above to wait for
#   Window's set command to finish dumping it's variables into the temp file
# - /b is will prevent a command shell to pop up
temp = tempfile.mktemp()
cmd = 'start /i /b cmd /c set>%s'%temp
p = subprocess.Popen(cmd, shell=True)
p.wait()

# Wait for the command to complete and parse the tempfile
data = []
while(is_locked(temp)):
    pass

with open(temp,'r') as file:
    data = file.readlines()
os.remove(temp)

# defaults will contain default env variables
defaults = dict()
for env in data:
    env = env.strip().split('=')
    defaults[env[0]]=env[1]

    print '%s %s'%(env[0],env[1])


os.environ = dict(defaults)

我的方式目前在 python 2.7.3 64 位中有效,但我只是注意到当我在 32 位中运行它时,PROGRAMFILES 和 PROGRAMFILES(x86) env 变量都指向“程序文件 (x86)”,这是一个讨论的问题here。

提前感谢您的所有帮助!

【问题讨论】:

  • 为什么不在进行任何更改之前推送设置?
  • @BrianCain 我想过这个问题,但我写这篇文章的原因是为了捕捉到我正在处理的模块在 os.environ 从它的默认值更改后会被调用的情况
  • 似乎您的模块可能没有足够的范围将os.environ 恢复到调用时的状态。

标签: python windows cmd environment-variables


【解决方案1】:

您可能需要类似question 中描述的modified_environ 上下文管理器来设置/恢复环境变量。

我建议你用这个上下文管理器来包装你的 main 函数:

with modified_environ():
    main()

这样,功能完成时一切都会恢复。

你也可以包装导入:

with modified_environ():
    import pkg.which.can.change.env
    main()

【讨论】:

    【解决方案2】:

    我想知道您的 hack 似乎有效,因为孩子继承父母的当前环境是设计使然。所以我认为除了在应用程序启动时保存环境之外别无选择。但是,这不一定是从开始菜单启动的 shell 的环境,因为您的父母也可以操纵它。

    进行以下实验:启动一个资源管理器,从中运行一个 shell 并调查环境。然后直接从开始菜单启动一个shell并再次检查。现在转到控制面板-> 系统并添加一个变量。重新启动两个 shell(但不是资源管理器)并注意区别。

    要获得“根”环境(登录时创建的环境),您可以在 HKCU/Environment 读取密钥。但这也可能是 hacky。

    【讨论】:

      猜你喜欢
      • 2021-08-08
      • 2016-07-04
      • 2014-01-18
      • 2016-11-19
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 2013-04-27
      相关资源
      最近更新 更多