Linux 上 Python 中的环境变量

2022-01-15 00:00:00 python environment-variables gdb

问题描述

Python 对环境变量的访问不能准确反映操作系统对进程环境的看法.

Python's access to environment variables does not accurately reflect the operating system's view of the processes environment.

os.getenv 和 os.environ 在特定情况下无法按预期运行.

os.getenv and os.environ do not function as expected in particular cases.

有没有办法正确获取运行进程的环境?

Is there a way to properly get the running process' environment?

为了说明我的意思,使用两个大致等效的程序(第一个用 C 语言,另一个用 python):

To demonstrate what I mean, take the two roughly equivalent programs (the first in C, the other in 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 附加到正在运行的进程,并通过执行以下操作强制更改引擎盖下的环境:


Now, if we run the C program and attach to the running process with gdb and forcibly change the environment under the hood by doing something like this:

(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 程序不会.

then the aforementioned C program will start spewing out "my value" once every 5 seconds. The aforementioned python program, however, will not.

在这种情况下,有没有办法让 python 程序像 C 程序一样运行?

Is there a way to get the python program to function like the C program in this case?

(是的,我意识到这是对正在运行的进程执行的非常晦涩且可能具有破坏性的操作)

(Yes, I realize this is a very obscure and potentially damaging action to perform on a running process)

另外,我目前使用的是 python 2.4,这可能已在更高版本的 python 中修复.

Also, I'm currently using python 2.4, this may have been fixed in a later version of python.


解决方案

这是一个非常好的问题.

That's a very good question.

原来 os 模块将 os.environ 初始化为 posix.environ,在解释器启动时设置.换句话说,标准库似乎不提供对 getenv 功能.

It turns out that the os module initializes os.environ to the value of posix.environ, which is set on interpreter start up. In other words, the standard library does not appear to provide access to the getenv function.

在这种情况下,在 unix 上使用 ctypes 可能是安全的.因为你会调用一个超标准的 libc 函数.

That is a case where it would probably be safe to use ctypes on unix. Since you would be calling an ultra-standard libc function.

相关文章