使用os.execlpe以root身份重新启动脚本时,PYTHONPATH变量丢失

时间:2017-06-15 05:13:50

标签: python

我的最终目标是拥有一个脚本,该脚本最初可由非特权用户启动而不使用sudo,但会提示输入sudo密码并自行提升为root。我一直在使用bash包装器脚本执行此操作,但希望更整洁,不需要额外的文件。

一些谷歌搜索发现this question on StackOverflow,其中接受的答案建议使用os.execlpe重新启动脚本,同时保留相同的环境。我试过了,但它在第二次运行时立即无法导入非内置模块。

调查显示PYTHONPATH变量没有结转,而几乎所有其他环境变量都是(PERL5LIB也缺失了,还有其他几个,但我没有使用它们,所以他们并没有麻烦我)。

我有一个简短的小测试脚本来演示这个问题:

#!/usr/bin/env python
import os
import sys

print(len(os.environ['PYTHONPATH']))

euid = os.geteuid()
if euid != 0:
    print("Script not started as root. Running with sudo.")
    args = ['sudo', sys,executable] + sys.argv + [os.environ]
    os.execlpe('sudo', *args)

print("Success")

预期输出为:

6548
Script not started as root. Running with sudo.
[sudo] password for esker:
6548
Success

但我得到了一个KeyError:

6548
Script not started as root. Running with sudo.
[sudo] password for esker:
Traceback (most recent call last):
  File "/usr/home/esker/execlpe_test.py", line 5, in <module>
    print(len(os.environ['PYTHONPATH']))
  File "/vol/apps/python/2.7.6/lib/python2.7/UserDict.py", line 23, in __getitem__
    raise KeyError(key)
KeyError: 'PYTHONPATH'

这个缺失变量的原因是什么,我怎样才能避免它消失?或者,是否有更好的方法可以解决这个问题?

1 个答案:

答案 0 :(得分:0)

您将环境作为参数传递给脚本而不是execlpe的参数。试试这个:

args = ['sudo', sys,executable] + sys.argv + [os.environ]
os.execvpe('sudo', args, os.environ)

如果你只想继承环境,你甚至可以

os.execvp('sudo', args)