[英]Environment Variables in Python on Linux
Python对环境变量的访问不能准确反映操作系统对进程环境的看法。
os.getenv和os.environ在特定情况下无法正常运行。
有没有办法正确获取正在运行的进程的环境?
为了演示我的意思,请使用两个大致等效的程序(第一个在C中,另一个在python中):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]){
char *env;
for(;;){
env = getenv("SOME_VARIABLE");
if(env)
puts(env);
sleep(5);
}
}
import os
import time
while True:
env = os.getenv("SOME_VARIABLE")
if env is not None:
print env
time.sleep(5)
现在,如果我们运行C程序并使用gdb附加到正在运行的进程,并通过执行以下操作来强行更改内部环境:
(gdb) print setenv("SOME_VARIABLE", "my value", 1)
[Switching to Thread -1208600896 (LWP 16163)]
$1 = 0
(gdb) print (char *)getenv("SOME_VARIABLE")
$2 = 0x8293126 "my value"
那么上述C程序将每5秒钟喷出一次“我的值”。 但是,上述python程序不会。
在这种情况下,有没有办法让python程序像C程序一样起作用?
(是的,我意识到这是一个非常模糊的操作,可能会对正在运行的进程执行破坏性的操作)
另外,我当前正在使用python 2.4,这可能已在更高版本的python中修复。
您可以使用ctypes
非常简单地执行此操作:
>>> from ctypes import CDLL, c_char_p
>>> getenv = CDLL("libc.so.6").getenv
>>> getenv.restype = c_char_p
>>> getenv("HOME")
'/home/glyph'
另一种可能性是改用pdb或其他一些python调试器,并在python级别而不是C级别更改os.environ。 这是我发布的一个小食谱,用于中断正在运行的python进程,并在接收到信号后提供对python控制台的访问。 或者,只需将pdb.set_trace()粘贴在您要中断的代码中的某个位置即可。 无论哪种情况,只要运行语句“ import os; os.environ['SOME_VARIABLE']='my_value'
”,就python而言,您应该进行更新。
我不确定这是否还会使用setenv更新C环境,因此,如果您直接使用getenv使用C模块,则可能需要做更多工作才能保持同步。
我不相信许多程序会期望从外部修改其环境,因此在启动时加载传递的环境的副本是等效的。 您只是偶然发现了一个实现选择。
如果您在程序中看到所有启动时设置的值和putenv / setenv,我认为没有什么可担心的。 有更干净的方法将更新的信息传递给正在运行的可执行文件。
查看Python源代码(2.4.5):
Modules / posixmodule.c在convertenviron()中获取环境,该环境在启动时运行(请参阅INITFUNC),并将环境存储在特定于平台的模块(nt,os2或posix)中
lib / os.py查看sys.builtin_module_names,并从posix,nt或os2导入所有符号
是的,它在启动时就决定了。 os.environ在这里不会有帮助。
如果您真的想这样做,那么想到的最明显的方法是创建一个自己的基于C的自定义python模块,并使用一个getenv始终调用系统调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.