我的最终目标是拥有一个脚本,该脚本最初可由非特权用户启动而不使用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'
这个缺失变量的原因是什么,我怎样才能避免它消失?或者,是否有更好的方法可以解决这个问题?
答案 0 :(得分:0)
您将环境作为参数传递给脚本而不是execlpe
的参数。试试这个:
args = ['sudo', sys,executable] + sys.argv + [os.environ]
os.execvpe('sudo', args, os.environ)
如果你只想继承环境,你甚至可以
os.execvp('sudo', args)