문제

Python의 환경 변수에 대한 액세스는 프로세스 환경에 대한 운영 체제의 관점을 정확하게 반영하지 않습니다.

os.getenv 및 os.environ은 특히 예상대로 작동하지 않습니다.

실행 프로세스 환경을 올바르게 얻는 방법이 있습니까?


내가 의미하는 바를 입증하기 위해 대략적으로 동등한 두 프로그램 (C의 첫 번째, 다른 하나는 파이썬)을 가져갑니다.

#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의 이후 버전에서 고정되었을 수 있습니다.

도움이 되었습니까?

해결책

그것은 아주 좋은 질문입니다.

그것은 그게 밝혀졌습니다 os 모듈 초기화 os.environ 의 가치에 posix.environ, 통역사 시작에 설정되어 있습니다. 다시 말해, 표준 라이브러리는 getenv 기능.

그것은 아마도 사용하기에 안전한 경우입니다. ctypes 유닉스에서. 초대형 LIBC 기능을 호출하기 때문입니다.

다른 팁

당신이 사용할 수있는 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 디버거를 대신 사용하고 C 레벨이 아닌 Python 레벨에서 OS.Environ을 변경하는 것입니다. 여기에 있습니다 실행중인 파이썬 프로세스를 방해하고 신호를 수신 할 때 파이썬 콘솔에 액세스 할 수 있도록 게시 한 작은 레시피. 또는 방해하려는 코드의 어느 시점에서 PDB.SET_TRACE ()를 고수하십시오. 두 경우 모두 성명서를 실행하십시오. "import os; os.environ['SOME_VARIABLE']='my_value'"그리고 파이썬에 관한 한 업데이트해야합니다.

이것이 SETENV로 C 환경을 업데이트할지 확실하지 않으므로 GetEnV를 직접 사용하는 C 모듈이있는 경우이를 동기화하기 위해 더 많은 작업을 수행해야 할 수도 있습니다.

많은 프로그램이 환경이 외부로 수정 될 것으로 기대하지 않으므로 스타트 업에서 통과 된 환경 사본을로드하는 것이 동일합니다. 당신은 단순히 구현 선택을 우연히 발견했습니다.

프로그램 작업 내에서 모든 시작 값과 putenv/setenv를보고 있다면 걱정할 것이 없다고 생각합니다. 업데이트 된 정보를 실행 실행 제품에 전달하는 훨씬 더 깨끗한 방법이 있습니다.

파이썬 소스 코드를보고 (2.4.5) :

  • Modules/PosixModule.c는 Startup에서 실행되는 Convertenviron ()에서 Environ을 가져 와서 플랫폼 별 모듈 (NT, OS2 또는 POSIX)에 환경을 저장합니다.

  • lib/os.py sys.builtin_module_names를보고 Posix, NT 또는 OS2에서 모든 기호를 가져옵니다.

그렇습니다. 스타트 업에서 결정됩니다. os.environ은 여기서 도움이되지 않을 것입니다.

정말로이 작업을 원한다면 가장 확실한 접근 방식은 항상 시스템 호출을 호출하는 getenv와 함께 자신의 Custom C 기반 Python 모듈을 만드는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top