【问题标题】:Launch a Python GUI from a C program running with user root从以 root 用户运行的 C 程序启动 Python GUI
【发布时间】:2013-06-18 12:15:20
【问题描述】:

我制作了一个 C 程序,它有时会调用它的 python GUI。

当使用 sudo 在我的桌面上同时运行 C 和 python 时,它可以正常工作,因为 sudo 正在以我的用户身份执行 C 程序。

但是,我创建了一个 systemd 单元以在启动时启动 C 代码,因此它由用户 root 执行,然后我无法让它在我的桌面上显示 Python GUI,因为我得到了WARNING **: Could not open X display

C 代码正在使用 inotify 监视二进制文件,并在打开二进制文件并通过简单的 system 调用打开 Python GUI 时执行一些工作。

C 代码必须以 root 权限执行,但 python GUI 可以作为普通用户启动,并在需要时使用 polkit 来获取它。它只需要在 /var/lib 本地化的 xml 文件中写入一些内容。

知道我该怎么做吗?

【问题讨论】:

    标签: python c root xorg


    【解决方案1】:

    第一种方式运行它的原因是DISPLAY环境变量在你启动C程序之前已经设置好了,它会被子进程继承。

    如果您在启动时启动 C 程序,则不会设置 DISPLAY 变量(可能),因此您需要在生成子进程之前设置它,例如...

    #include <stdlib.h>
    
    setenv("DISPLAY", something, 1);
    // Now launch the Python script
    

    棘手的一点是为something 输入的内容。它必须是您在常规 X11 会话中执行 echo $DISPLAY 时获得的任何内容,假设 C 程序与您的 X11 会话在同一系统上运行。

    您要么必须硬编码一个有效的值,要么找到某种方法将正确的值传递给 C 程序。


    更新

    关于权限问题 - 一个简单的解决方法是将 xhost +root 放入 ~/.xsession,假设您信任 root。

    否则,您可以强制 Python 脚本作为您的 UID 运行。您可以执行正确的 fork-exec 操作,并在调用 exec() 之前在子进程中调用 setuid(2),或者您可以在 Python 脚本的顶部调用 os.setuid()

    【讨论】:

    • 显示可以硬编码为 :0 但如果我之前不执行 xhost + 则它不起作用,并且我无法从 C 代码执行该命令,因为它运行为根对吗?
    • 如果您以 root 身份运行该命令,您应该能够告诉它也使用您的 X 授权。在您调用system() 启动应用程序之前,将XAUTHORITY 环境变量设置为“/pathto/user/homedir/.Xauthority”。这应该足够了,而不是使用xhost 命令。
    • 我尝试了你们所说的混合。我创建了一个 ID 为 627 的用户,并在代码顶部使用 xhost +SI:localuser:username, then on the python code I set os.setuid(627)` 授予它权限,所以当我编写 print(os.getuid())我得到正确的 627。仍然出现相同的消息。 Edelson 的想法有个问题,我不知道哪个用户会看到 Python GUI。
    • @user712533 TBH,我对 X11 权限系统不是特别熟悉,但即使你可以让它工作,拥有一个守护进程似乎有点 hacky ,以 root 身份运行,生成一个针对任意 X11 会话的 GUI。如果没有用户登录应该怎么办,或者如果您希望 GUI 对多个用户可见怎么办?一种更灵活的方法是让“感兴趣的”用户自己运行 X11 程序,并让它与守护进程进行 IPC。
    猜你喜欢
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 2013-07-04
    • 2016-11-23
    • 1970-01-01
    • 2010-10-08
    相关资源
    最近更新 更多