有没有办法像已知程序一样解决身份验证问题?

Is there way to solve authentication like the known programs?

我在 Python 中有一个程序。我希望程序启动时要求我在 GUI 对话框中输入 root 密码。我 运行 程序然后显示以下错误:

couldn't connect to display ": 0.0"

如果我删除所有在 upgrade.py 中带有 pkexec 内容的行,那么它就可以完美运行。另外,如果我在 gnome-terminal 中 运行 使用命令 sudo python3 /home/user/Python/upgrade.py 那么它也可以工作。也许是 sudo 的问题? Python.

的 GTK 完全一样

Python代码:

from tkinter import *
#!/usr/bin/python3
import os
import subprocess
import sys

euid = os.geteuid()
if euid != 0:
    print ("Script not started as root. Running sudo..")
    args = ['pkexec', sys.executable] + sys.argv + [os.environ]
    # the next line replaces the currently-running process with the sudo
    os.execlpe('pkexec', *args)

print ('Running. Your euid is', euid)


root = Tk()
root.title('Update system')
#root.geometry("290x100")

def button_add1():
    callProcess = subprocess.Popen(['ls', '-la'], shell=True)
    subprocess.run(['pkexec', 'ls', '-la'], check=True)

def button_add4():
    root.destroy()

# Define Buttons

button_1 = Button(root, text="Upgrade system",  padx=40, pady=20, command=button_add1)
button_4 = Button(root, text="Quit", padx=40, pady=20, command=button_add4)

# Put the buttons on the screen

button_1.grid(row=0, column=0)
button_4.grid(row=0, column=4)

root.mainloop()

拜托,我不想要这样的东西... Simplest method of asking user for password using graphical dialog in Python?

我想要像 SynapticGpartedBleachbit

这样的程序进行身份验证

我有 already asked on Whosebug 但他们说,它与系统策略配置有关,与 Python 或 tkinter 无关。此问题现已迁移回 Stack Overflow!

我在 Debian 和 Linux Mint 上尝试了我的代码。

您不得尝试 运行 GUI 为 root。您应该隔离尽可能小的组件,并且只隔离 运行 作为特权的组件。请参阅 https://wiki.archlinux.org/index.php/Running_GUI_applications_as_rootpkexec 手册页中的注释,其中专门解释了它不允许您接管调用用户的 $DISPLAY

这是一个粗略的草图,但现在还没有经过测试。

#!/usr/bin/python3
# ^ this needs to be the absolutely first line of the file

from tkinter import *   # FIXME: probably avoid import *
# import os   # no longer used
import subprocess
# import sys  # no longer used

print ('Running. Your euid is whatever it is.')


root = Tk()
root.title('Update system')
#root.geometry("290x100")

def button_add1():
    subprocess.run(['ls', '-la'], check=True)
    subprocess.run(['pkexec', 'ls', '-la'], check=True)

def button_add4():
    root.destroy()

# Define Buttons

button_1 = Button(root, text="Upgrade system",  padx=40, pady=20, command=button_add1)
button_4 = Button(root, text="Quit", padx=40, pady=20, command=button_add4)

# Put the buttons on the screen

button_1.grid(row=0, column=0)
button_4.grid(row=0, column=4)

root.mainloop()

如果(如在您编辑之前的代码中那样)您想要 运行 一个 pkexec 后面的多个命令,您可以使用

之类的东西来做到这一点
    subprocess.run(
        ['pkexec', 'sh', '-c', 'apt-get update && apt-get upgrade -y'],
        check=True)

顺便说一句,如果您的示例代码具有代表性,您可以将 from tkinter import * 替换为 from tkinter import Tk 以避免 import * 反模式。