简体   繁体   English

pygame.display.init() 对于非 root 用户失败

[英]pygame.display.init() fails for non-root user

Tl;dr Tl;博士

I need to use pygame but it can't initialize the screen as a normal user because of the permissions for the framebuffer driver .我需要使用pygame但由于帧缓冲区驱动程序的权限,它无法以普通用户身份初始化屏幕。 root can do pygame.display.init() but not the user. root 可以做pygame.display.init()但不是用户。 User is in the group 'video' and can write on /dev/fb0 .用户在组 'video' 中,可以在/dev/fb0上写入。 What permission is missing to the user so pygame.display.init() would work.用户缺少什么权限,所以pygame.display.init()可以工作。
Error encountered: pygame.error: Unable to open a console terminal遇到的错误: pygame.error: Unable to open a console terminal

Description描述

So, I am trying to use pygame in order to display things on a framebuffer /dev/fb0 .因此,我正在尝试使用pygame在帧缓冲区/dev/fb0上显示内容。 To use some functions I need (eg pygame.Surface.convert ) the display must be initialized.要使用我需要的某些功能(例如pygame.Surface.convert ),必须初始化显示器。 However, when calling pygame.display.init() I have an error, but only when not doing so as root.但是,在调用pygame.display.init()时出现错误,但仅在不以 root 身份调用时出现。

According to @Nodraak (ref) it is related to the permissions of the framebuffer driver .根据@Nodraak (ref) ,它与framebuffer driver的权限有关。

Late answer but I wish I would have tried that earlier:迟到的答案,但我希望我早点尝试过:

You may need to be root to use a frame buffer driver.您可能需要成为 root 才能使用帧缓冲区驱动程序。

(It helped in my case: RaspberryPi 2 without X running but with a screen connected. I can now open a display through SSH or directly on the RPi) (在我的情况下它有所帮助:RaspberryPi 2 没有运行 X,但连接了屏幕。我现在可以通过 SSH 或直接在 RPi 上打开显示器)

A tree -fupg / | grep fb | grep rwxtree -fupg / | grep fb | grep rwx tree -fupg / | grep fb | grep rwx tree -fupg / | grep fb | grep rwx doesn't seem to show any binary which would be executable by root but not by others. tree -fupg / | grep fb | grep rwx似乎没有显示任何可由 root 执行但不能由其他人执行的二进制文件。 I am quite sure that adding my user to a group, or tweaking the file permissions somewhere would be enough to fix the issue.我很确定将我的用户添加到组中,或在某处调整文件权限就足以解决问题。

Note: For Security reasons, running the software as root is not an option.注意:出于安全原因,不能以 root 身份运行该软件。

Context语境

  • System: RaspberryPi系统:树莓派
  • X Server: None X 服务器:无
  • Screen: 1 (HDMI)屏幕:1(HDMI)
  • Connection: remote (SSH)连接:远程(SSH)

Origin of the error错误的根源

I am trying to convert a surface with pygame.Surface.convert(...) function.我正在尝试使用pygame.Surface.convert(...) function 转换表面。 But receive the following error:但收到以下错误:

pygame.error: cannot convert without pygame.display initialized

Nevertheless, initializing pygame.display with pygame.display.init() is giving the following error:尽管如此,使用pygame.display.init()初始化 pygame.display 会出现以下错误:

pygame.error: Unable to open a console terminal

I have the rights to write to the screen as I am part of the video group, and cat /dev/urandom > /dev/fb0 is effectively displaying snow on the screen.作为video组的一员,我有权在屏幕上写字,并且cat /dev/urandom > /dev/fb0正在有效地在屏幕上显示雪。

Also I tried setting up the SDL_... environment variable to fbcon or dummy but it doesn't help.我也尝试将 SDL_... 环境变量设置为fbcondummy ,但它没有帮助。 I also tried keeping the root env with user su -m user and same result.我还尝试将 root env 与用户su -m user保持一致,结果相同。

Reproduce the error重现错误

On a raspberrypi without XServer, connect an HDMI screen, install pygame.在没有 XServer 的树莓派上,连接 HDMI 屏幕,安装 pygame。

import pygame
pygame.display.init()

Error message:错误信息:
pygame.error: Unable to open a console terminal

Software Versions软件版本

python     3.7.3
pygame     1.9.4.post1
OS         Raspbian Buster
libsdl     2

Related有关的

Solution to the problem问题的解决方案

OpenVT开放式VT

So it appears that the best solution, which meet all requirement I listed, is to use openvt .因此,满足我列出的所有要求的最佳解决方案似乎是使用openvt

How?如何?

The procedure holds in a few bullet points:该过程包含几个要点:

1. Add User to tty group 1. 将用户添加到tty

As root, add your user to the group named tty , that will allow us to give it access to the TTYs.以 root 身份将您的用户添加到名为tty的组中,这将允许我们授予它访问 TTY 的权限。

# As root:
usermod -a -G tty $username

2. Give TTY access to users in group tty 2. 给组tty中的用户授予 TTY 访问权限

Now that the user is part of the group tty we need it to be allowed to write on it, as openvt will use a tty.现在用户是组tty的一部分,我们需要允许它在上面写,因为 openvt 将使用 tty。 By default, the mode should be set at 620 we need to set it at 660 to allow the group to write on it.默认情况下,模式应设置为620 ,我们需要将其设置为660以允许组在其上写入。

# Edit file: /lib/udev/rules.d/50-udev-default.rules
SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660"
#                                      ensure mode is 0660  ^

3. Set SDL environment variables 3.设置SDL环境变量

Inside your software, make sure to set up the environment variables of SDL.在您的软件中,确保设置 SDL 的环境变量。

import os
# ...
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
os.environ["SDL_FBDEV"] = "/dev/fb0"

4. Reboot the Raspberry 4.重启树莓派

Ok, you don't need a snippet for that.. Whether?好的,你不需要一个片段......是否? Well ok.好吧。

# as root / with sudo
reboot

5. Start software with openvt 5.用openvt启动软件

openvt (open Virtual Terminal) allows us to run the interface directly with screen access. openvt (打开虚拟终端)允许我们通过屏幕访问直接运行界面。 This must be executed by the final user, in the same directory as the software (preferably).这必须由最终用户在与软件相同的目录中执行(最好)。

openvt -s -- python3 ./interface.py

And that should work.这应该有效。
Of course you can then integrate this in a Linux service so it starts at boot.当然,您可以将其集成到 Linux 服务中,以便它在启动时启动。 but you may need to add After: getty@tty1.service in the [Unit] section of the service file.但您可能需要在服务文件的[Unit]部分添加After: getty@tty1.service

Well, it took me lots of time to figure that one out, so I hope it helps someone else as well.好吧,我花了很多时间才弄清楚这一点,所以我希望它也能帮助其他人。

The files in /dev/fb* are owned by root. /dev/fb*中的文件归 root 所有。

$ ls -l /dev/fb*
crw-rw---- 1 root video 29, 0 Jan 25 19:48 /dev/fb0
crw-rw---- 1 root video 29, 1 Jan 25 20:52 /dev/fb1

That's why You can't use it as a normal user, but only as a root as You mentioned in Your post.这就是为什么您不能将其用作普通用户,而只能用作您在帖子中提到的根用户。

As You can see, the allowed group is called video for both FrameBuffers.如您所见,允许的组称为两个 FrameBuffers 的video
Adding Your user into video group should solve Your issue:将您的用户添加到视频组应该可以解决您的问题:

usermod -a -G video username

I ran into the same problem trying to use pygame as a permanent display.我在尝试使用 pygame 作为永久显示器时遇到了同样的问题。

I decided have the pi autostart on boot, which works and starts your pygame code as root.我决定让 pi 在启动时自动启动,它可以以 root 身份启动 pygame 代码。

To activate autostart, add lines to start your code into要激活自动启动,请添加行以启动您的代码

/etc/rc.local /etc/rc.local

above the exit 0 line.exit 0线上方。

For example (I have the code in '/opt/pygame_prototype/pg.py')例如(我在'/opt/pygame_prototype/pg.py'中有代码)

cd /opt/pygame_prototype
/usr/bin/python3 pg.py

Then on boot, the pi will not go to the login, but start the pygame program.然后在启动时,pi 不会 go 登录,而是启动 pygame 程序。

Note: Use the "apt get " installed pygame without a virtual environment, the newer pip installed version failed me.注意:在没有虚拟环境的情况下使用“apt get”安装 pygame,较新的 pip 安装版本失败了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM