我正在编写一个构建脚本来解析依赖的共享库(及其共享库等)。普通的PATH
环境变量中不存在这些共享库。
为了使构建过程起作用(编译器找到这些库),PATH
已被更改为包含这些库的目录。
因此构建过程是:
Loader脚本(更改PATH) - >基于Python的构建脚本 - >配置 - >构建 - >解决依赖关系 - >安装。
Python实例从其父shell继承了一个已更改的PATH
变量。
在Python中,我正在尝试获取默认的PATH
(不是从其父shell继承的那个)。
这个想法:
解决'默认'PATH变量的想法是以某种方式“发出信号”操作系统启动一个新进程(运行打印PATH的脚本),但这个过程不是一个孩子的当前的Python进程(并且可能不会继承其修改的环境变量)。
尝试实施:
import os
import sys
print os.environ["PATH"]
print "---"
os.spawnl(os.P_WAIT, sys.executable, "python", "-c \"import os;print(os.environ['PATH']);\"")
os.spawn
似乎使用与调用它的Python进程相同的环境变量。我也用subprocess.POpen
尝试过这种方法,但没有成功。
这种方法可以实施吗?如果没有,什么是替代方法(假设加载器脚本和整个过程不能改变)?
我目前正在使用Windows,但构建脚本是跨平台的。
修改
跨平台约束似乎过于严格。现在可以考虑相同概念的不同实现。
例如,使用this回答中的代码,Windows注册表可用于获取“默认”系统PATH
变量。
try:
import _winreg as winreg
except ImportError:
try:
import winreg
except ImportError:
winreg = None
def env_keys(user=True):
if user:
root = winreg.HKEY_CURRENT_USER
subkey = "Environment"
else:
root = winreg.HKEY_LOCAL_MACHINE
subkey = r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
return root, subkey
def get_env(name, user=True):
root, subkey = env_keys(user)
key = winreg.OpenKey(root, subkey, 0, winreg.KEY_READ)
try:
value, _ = winreg.QueryValueEx(key, name)
except WindowsError:
return ""
value = winreg.ExpandEnvironmentStrings(value)
return value
print get_env("PATH", False)
需要一致的* nix方法。
答案 0 :(得分:2)
使用subprocess.Popen
,您可以为子进程提供使用环境:
default_path = os.environ['PATH'] # save the default path before changing it
os.environ['PATH'] = # whatever you want
child_env = os.environ.copy()
child_env['PATH'] = default_path
# change env
subprocess.Popen(..., env=child_env)
documentation表示将使用提供的环境而不是从父级继承它:
如果env不是None,则它必须是定义环境的映射 新过程的变量;这些用于代替继承 当前进程的环境,这是默认行为。
答案 1 :(得分:0)
默认'你的意思是什么? PATH的价值?登录时的值是多少?某些系统范围的默认值?加载程序脚本在更改之前启动的值?
最简单的方法是使用您自己的一个来装入加载器脚本(如果您真的无法更改它),将PATH的当前值保存在某些其他环境变量(如OLD_PATH)中。然后你可以使用类似的东西:
os.spawnle( ... , {'PATH' : os.environ['OLD_PATH']})
或者你可以将shell作为登录或至少交互式shell生成,并在调用python之前让它来源用户的.bashrc(或其他启动)。
**更新**用于Windows,并假设您只想获取PATH:
Spawn CMD.EXE,让它执行命令' echo%PATH%'