如果非root用户针对root拥有的文件运行以下代码,则会抛出错误,即使非root用户具有sudo权限:
try:
f = open(filename, "w+")
except IOError:
sys.stderr.write('Error: Failed to open file %s' % (filename))
f.write(response + "\n" + new_line)
f.close()
有没有办法使用sudo权限运行open(filename, "w+")
,或者执行此操作的替代函数?
答案 0 :(得分:6)
您有几个选择:
os.geteuid() != 0
),然后使用sudo
infront(要求用户输入密码)自行呼叫并退出:
import os
import sys
import subprocess
if os.geteuid() == 0:
print("We're root!")
else:
print("We're not root.")
subprocess.call(['sudo', 'python3', *sys.argv])
调用它看起来像这样:
$ python3 be_root.py
We're not root.
Password:
We're root!
答案 1 :(得分:5)
L3viathan's reply 有一个SynaxError 编辑:在Python 3.5+上运行正常。这是Python 3.4.3的一个版本(在Ubuntu 16.04上默认发布)及以下版本:
if os.geteuid() == 0:
# do root things
else:
subprocess.call(['sudo', 'python3'] + sys.argv) # modified
但是,我采用了不同的方法,因为它使我的用例中的代码更简单:
if os.geteuid() != 0:
os.execvp('sudo', ['sudo', 'python3'] + sys.argv)
# do root things
L3viathan's reply取决于PEP 448,它包含在Python 3.5中,并引入了允许星形参数扩展的其他上下文。对于Python 3.4及更低版本,列表连接可用于执行相同的操作:
import os
import sys
import subprocess
if os.geteuid() == 0:
print("We're root!")
else:
print("We're not root.")
subprocess.call(['sudo', 'python3'] + sys.argv) # modified
但注意: subprocess.call()
启动子进程,这意味着在root完成运行脚本后,原始用户也将继续运行其脚本。这意味着您需要将提升的逻辑放在if/else
块的一侧,这样当原始脚本完成时,它不会尝试运行任何需要提升的逻辑(L3viathan&'s示例)这样做。)
这不一定是坏事 - 这意味着正常/提升的逻辑可以写在同一个脚本中并且很好地分开 - 但是我的任务需要所有逻辑的根。如果另一个块空无一人,我不想浪费一个缩进级别,我还没有意识到使用子进程会影响事情,所以我尝试了这个:
import os
import sys
import subprocess
if os.geteuid() != 0:
subprocess.call(['sudo', 'python3'] + sys.argv)
# do things that require root
...它当然打破了,因为在root完成后,普通用户恢复执行其脚本并尝试运行需要root的语句。
然后我发现this Gist推荐os.execvp()
- 它取代了正在运行的进程,而不是启动一个孩子:
import os
import sys
if os.geteuid() != 0:
os.execvp('sudo', ['sudo', 'python3'] + sys.argv) # final version
# do things that require root
这看似按预期运行,保存缩进级别和3行代码。
警告:我十分钟前都不知道os.execvp()
,并且对于使用它可能存在的陷阱或细微之处一无所知。 YMMV。
答案 2 :(得分:1)
如果您实际上没有使用它,则有可能使用sudo
不会给您任何特权。因此,正如其他人建议您可能应该使用sudo
启动您的程序。但如果你不喜欢这个想法(我没有看到任何理由),你可以做其他的伎俩。
您的脚本可以检查是否以root权限运行,或者它是否仅以用户权限运行。比脚本实际上可以使用更高的权限运行自己。这里有一个例子(请注意,在源代码中存储密码不是一个好主意)。
import os.path
import subprocess
password_for_sudo = 'pass'
def started_as_root():
if subprocess.check_output('whoami').strip() == 'root':
return True
return False
def runing_with_root_privileges():
print 'I have the power!'
def main():
if started_as_root():
print 'OK, I have root privileges. Calling the function...'
runing_with_root_privileges()
else:
print "I'm just a user. Need to start new process with root privileges..."
current_script = os.path.realpath(__file__)
os.system('echo %s|sudo -S python %s' % (password_for_sudo, current_script))
if __name__ == '__main__':
main()
输出:
$ python test.py
I'm just a user. Need to start new process with root privileges...
OK, I have root privileges. Calling the function...
I have the power!
$ sudo python test.py
OK, I have root privileges.
Calling the function...
I have the power!
答案 3 :(得分:0)
您的脚本仅限于运行它的权限,因为您无法在没有root权限的情况下更改用户。
正如Rob所说,在不更改文件权限的情况下执行此操作的唯一方法是使用sudo
运行。
sudo python ./your_file.py
答案 4 :(得分:0)
另一种选择是将文件写入您有权访问的目录,然后sudo mv
将文件写入您无权访问的目录。