2012-06-08 21 views
29

Tengo una pequeña aplicación de Python, lanzada a través de subprocess.Popen, que toma algunos parámetros en forma de variables de entorno. Lo hago pasando la estructura de entorno a la llamada Popen. El programa luego lee las variables a través de os.getenv.¿Cuándo os.environ ['foo'] no coincide con os.getenv ('foo')?

O más bien, solía leerlos de esa manera. En Windows, funcionó bien. Pero en nuestros servidores FreeBSD, os.getenv devuelve None para todos los parámetros que se ha pasado. La parte extraña es que os.environ tiene los valores simplemente finas — y, de hecho, simplemente cambiando todos los os.getenv('foo') llamadas a os.environ['foo'] trabajo todo lo hizo muy bien en ambos plataformas .

¿Por qué son diferentes estos valores? ¿Cuándo es apropiado uno sobre el otro?

Respuesta

17

os.environ se crea en la importación del módulo os, y no refleja los cambios en el entorno que ocurren después a menos que se modifique directamente. Curiosamente, sin embargo, os.getenv() tampoco obtiene las variables de entorno más recientes, al menos no en CPython. Usted ve, en CPython, os.getenv() es aparentemente solo un contenedor alrededor de os.environ.get() (vea http://hg.python.org/cpython/file/6671c5039e15/Lib/os.py#l646). Parece que la razón principal para usar os.getenv() con la implementación indicada es cuando desea que se devuelva un valor predeterminado cuando no se encuentra un nombre de variable de entorno en las claves os.environ en lugar de tener un KeyError o lo que sea, y desea guarda algunos personajes

Es completamente posible que la implementación en FreeBSD tenga algún truco extraño que haga que actúe de manera diferente, pero no estoy seguro de por qué sería ese el caso. Eche un vistazo a la copia de os.py en una de las máquinas FreeBSD que use, si puede.

+0

En Windows 10, 'os.putenv ('abc', '123')' no funcionó, es decir, la nueva variable no está configurada. Sin embargo, 'os.environ ['abc'] = '123'' funciona y, posteriormente,' os.getenv (' abc ') 'también funciona. –

+1

@arvindpdmn Después de otro examen, eso es porque 'putenv()' en realidad no almacena la variable de entorno en 'os.environ'; más bien, 'environ .__ setitem __()' llama a 'putenv()' y también almacena los datos localmente, y ni 'getenv()' ni 'environ .__ getitem __()' realmente consultan el entorno en sí, operan fuera de lo que sea 'os .environ' ha almacenado. Una forma bastante confusa de implementarlo. – JAB

Cuestiones relacionadas