python os.environ, os.putenv, / usr / bin / env

Quiero asegurar que os.system('env') no contenga alguna variable específica myname que se exporte en ~/.bashrc como export myname=csj

Por lo tanto, escribí a continuación el código de Python:

 import os def print_all(): print "os.environ['myname']=%s" % os.environ.get('myname') print "os.getenv('myname')=%s" % os.getenv('myname') os.system('env | grep myname') print def delete_myname(): if 'myname' in os.environ: os.environ.pop('myname') if os.getenv('myname'): os.unsetenv('myname') print_all() os.putenv('myname', 'csj2') print "---------------------" delete_myname() print_all() os.putenv('myname', 'csj3') print "---------------------" delete_myname() print_all() 

Creo que examinar tanto os.environ['myname'] como os.getenv('myname') y luego eliminarlos si existen, puede asegurar que os.system('env | grep myname') no obtenga nada.

Sin embargo, el resultado es:

 os.environ['myname']=csj os.getenv('myname')=csj myname=csj --------------------- os.environ['myname']=None os.getenv('myname')=None --------------------- os.environ['myname']=None os.getenv('myname')=None myname=csj3 

No entiendo por qué todavía tengo csj3 en os.system('env | grep myname') ?

De los documentos :

Nota: Llamar a putenv () directamente no cambia os.environ, por lo que es mejor modificar os.environ.

Para unsetenv existe una advertencia similar:

sin embargo, las llamadas a unsetenv () no actualizan os.environ, por lo que en realidad es preferible eliminar elementos de os.environ.

getenv simplemente devuelve el valor de os.environ , como se muestra en su implementación , por lo que al usarlo se llega a un estado en el que parece que el valor no se establece cuando se busca en python, mientras que en realidad está en el entorno real. La única forma de obtenerlo ahora que puedo pensar sería llamar a la función c getenv usando ctypes …

Si os.environ su código para usar os.environ trata de llamar putenv / unsetenv todo funciona como se esperaba:

 import os def print_all(): print "os.environ['myname']=%s" % (os.environ['myname'] if 'myname' in os.environ else "None") os.system('env | grep myname') print def delete_myname(): if 'myname' in os.environ: os.environ.pop('myname') print_all() os.environ['myname'] = 'csj2' print "---------------------" print_all() delete_myname() print_all() os.environ['myname'] = 'csj3' print "---------------------" print_all() delete_myname() print_all() 

salida:

 $ myname=somevalue python2 test.py os.environ['myname']=somevalue myname=somevalue --------------------- os.environ['myname']=csj2 myname=csj2 os.environ['myname']=None --------------------- os.environ['myname']=csj3 myname=csj3 os.environ['myname']=None 

Una buena práctica podría ser:

  • eliminar la variable de entorno myname (si existe),
  • ejecuta tu función
  • restaurar la variable de entorno myname al finalizar la función.

Yu puede hacerlo fácilmente con algo como lo describe el administrador de contexto modified_environ en esta pregunta .

 with modified_environ('myname'): call_my_function()