2013-07-17 8 views
12

voglio assicurare os.system('env') non contiene qualche variabile specifica myname che è l'esportazione in ~/.bashrc come export myname=csjpitone os.environ, os.putenv,/usr/bin/env

Pertanto, ho scritto qui di seguito codice 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() 

Penso esaminare sia os.environ['myname'] e os.getenv('myname') e quindi eliminarli, se esiste, può garantire os.system('env | grep myname') ottiene nulla.

Tuttavia, il risultato è:

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 

Non capisco il motivo per cui ho ancora avuto csj3 su os.system('env | grep myname')?

+0

Sembra che si verifichi una condizione di competizione. Hai gli stessi risultati in modo coerente?Se aggiungi un quarto round, 'myname = csj3' persist, o solo' myname = csj4' nel quarto round? – chepner

+0

ha sempre lo stesso risultato. In realtà, nel mio vero script python, ci sono molte cose/codice tra il secondo putenv(), mi confondono molto. Ora ho messo un time.sleep (1) prima del 2 ° putenv(), e 'while [1]; do python env.py; dormire 1; fatto per eseguire lo script, ha sempre ottenuto lo stesso risultato. – CSJ

+0

se elimino una riga 'if 'myname' in os.environ: os.environ.pop ('myname')', sorprendentemente, non ho ottenuto nulla su 'os.system ('env | grep myname')' e sembra risolvere il problema. Anche se non so ancora perché ... – CSJ

risposta

12

Dal docs:

Nota: Calling putenv() direttamente non cambia os.environ, quindi è meglio modificare os.environ.

Per unsetenv c'è un warining simile:

tuttavia, chiamate a unsetenv() non aggiornano os.environ, quindi è effettivamente preferibile eliminare gli elementi di os.environ.

getenv solo restituisce il valore da os.environ, come è implementation shows, quindi usandolo si entra in uno stato in cui sembra che il valore non è impostato quando si guarda in su in pitone, mentre è acutally nel ambiente reale. L'unico modo per farlo ora mi viene in mente sarebbe quello di chiamare la funzione C getenv utilizzando ctypes ...

Se modifico il codice per utilizzare os.environ isnstead di chiamare putenv/unsetenv tutto funziona come previsto:

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() 

uscita:

$ 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 
+0

Sì, penso che se usi solo os.environ puoi garantire a/usr/bin/env di non avere la variabile ... ma perché lo script di altre squadre usa putenv() per fare qualcosa, e chiamo la loro sceneggiatura. Non ho una buona ragione per convincerli a cambiare il loro codice. Voglio solo provare a eliminarlo da solo. – CSJ

+2

Mostra loro la nota nella documentazione per putenv/unsetenv, e che getenv restituisce semplicemente ciò che si trova in 'os.environ'. Questo dovrebbe convincerli. – mata

0

Una buona pratica potrebbe essere:

  • eliminare la variabile myname ambiente (se esiste),
  • gestiscono la funzione
  • ripristinare la variabile d'ambiente myname al termine della funzione.

Yu può farlo facilmente con qualcosa come il modified_environ contesto direttore descrivere in questo question.

with modified_environ('myname'): 
    call_my_function()