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

python os.environ、os.putenv、/usr/bin/env,python,Python,我想确保os.system('env')不包含某些特定变量myname 它在~/.bashrc中导出为export myname=csj 因此,我编写了以下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(

我想确保
os.system('env')
不包含某些特定变量
myname
它在
~/.bashrc
中导出为
export myname=csj

因此,我编写了以下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()
我想检查一下
os.environ['myname']
os.getenv('myname')
然后删除它们(如果存在), 可以确保操作系统('env | grep myname')一无所获

然而,结果是:

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
我不明白为什么我仍然在
os.system('env | grep myname')
上获得
csj3

注意:直接调用putenv()不会改变os.environ,因此最好修改os.environ

对于
unsetenv
有一个类似的警告:

但是,对unsetenv()的调用不会更新os.environ,因此实际上最好删除os.environ的项

getenv
只返回来自
os.environ
的值,因为它是真实的,所以通过使用它,您会进入一种状态,当您从python中查找它时,该值似乎没有设置,而实际上它是在真实的环境中。现在我能想到的唯一方法是使用ctypes调用c getenv函数

如果我将您的代码修改为使用
os.environ
而不是调用
putenv
/
unsetenv
则一切正常:

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()
输出:

$ 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

一个好的做法可以是:

  • 删除
    myname
    环境变量(如果存在)
  • 运行你的函数
  • 在函数完成时还原
    myname
    环境变量
Yu可以很容易地使用本文描述的
modified_environ
上下文管理器这样的工具来实现这一点


看起来好像发生了某种种族状况。你得到的结果一致吗?如果您添加了第四轮,那么
myname=csj3
是持续存在,还是仅在第四轮中添加
myname=csj4
?它总是得到相同的结果。实际上,在我真正的python脚本中,第二个putenv()之间有很多东西/代码,这让我很困惑。现在我在第二个putenv()之前加了一个时间。sleep(1)和
while[1];执行python env.py;睡眠1;如果我在os.environ:os.environ.pop('myname')中删除一行
if'myname'('myname')
,令人惊讶的是,我在
os.system('env | grep myname')
上什么都没有,似乎解决了问题。虽然我仍然不知道为什么…是的,我认为如果只使用os.environ可以确保/usr/bin/env没有变量。。。但是因为其他团队的脚本使用putenv()来做一些事情,所以我调用他们的脚本。我没有很好的理由说服他们修改代码。我只想自己尝试删除它。向他们显示putenv/unsetenv文档中的注释,getenv只返回
os.environ
中的内容。这应该能说服他们。
with modified_environ('myname'):
    call_my_function()