繁体   English   中英

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

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

Tl;博士

我需要使用pygame但由于帧缓冲区驱动程序的权限,它无法以普通用户身份初始化屏幕。 root 可以做pygame.display.init()但不是用户。 用户在组 'video' 中,可以在/dev/fb0上写入。 用户缺少什么权限,所以pygame.display.init()可以工作。
遇到的错误: pygame.error: Unable to open a console terminal

描述

因此,我正在尝试使用pygame在帧缓冲区/dev/fb0上显示内容。 要使用我需要的某些功能(例如pygame.Surface.convert ),必须初始化显示器。 但是,在调用pygame.display.init()时出现错误,但仅在不以 root 身份调用时出现。

根据@Nodraak (ref) ,它与framebuffer driver的权限有关。

迟到的答案,但我希望我早点尝试过:

您可能需要成为 root 才能使用帧缓冲区驱动程序。

(在我的情况下它有所帮助:RaspberryPi 2 没有运行 X,但连接了屏幕。我现在可以通过 SSH 或直接在 RPi 上打开显示器)

tree -fupg / | grep fb | grep rwx tree -fupg / | grep fb | grep rwx tree -fupg / | grep fb | grep rwx似乎没有显示任何可由 root 执行但不能由其他人执行的二进制文件。 我很确定将我的用户添加到组中,或在某处调整文件权限就足以解决问题。

注意:出于安全原因,不能以 root 身份运行该软件。

语境

  • 系统:树莓派
  • X 服务器:无
  • 屏幕:1(HDMI)
  • 连接:远程(SSH)

错误的根源

我正在尝试使用pygame.Surface.convert(...) function 转换表面。 但收到以下错误:

pygame.error: cannot convert without pygame.display initialized

尽管如此,使用pygame.display.init()初始化 pygame.display 会出现以下错误:

pygame.error: Unable to open a console terminal

作为video组的一员,我有权在屏幕上写字,并且cat /dev/urandom > /dev/fb0正在有效地在屏幕上显示雪。

我也尝试将 SDL_... 环境变量设置为fbcondummy ,但它没有帮助。 我还尝试将 root env 与用户su -m user保持一致,结果相同。

重现错误

在没有 XServer 的树莓派上,连接 HDMI 屏幕,安装 pygame。

import pygame
pygame.display.init()

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

软件版本

python     3.7.3
pygame     1.9.4.post1
OS         Raspbian Buster
libsdl     2

有关的

问题的解决方案

开放式VT

因此,满足我列出的所有要求的最佳解决方案似乎是使用openvt

如何?

该过程包含几个要点:

1. 将用户添加到tty

以 root 身份将您的用户添加到名为tty的组中,这将允许我们授予它访问 TTY 的权限。

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

2. 给组tty中的用户授予 TTY 访问权限

现在用户是组tty的一部分,我们需要允许它在上面写,因为 openvt 将使用 tty。 默认情况下,模式应设置为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.设置SDL环境变量

在您的软件中,确保设置 SDL 的环境变量。

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

4.重启树莓派

好的,你不需要一个片段......是否? 好吧。

# as root / with sudo
reboot

5.用openvt启动软件

openvt (打开虚拟终端)允许我们通过屏幕访问直接运行界面。 这必须由最终用户在与软件相同的目录中执行(最好)。

openvt -s -- python3 ./interface.py

这应该有效。
当然,您可以将其集成到 Linux 服务中,以便它在启动时启动。 但您可能需要在服务文件的[Unit]部分添加After: getty@tty1.service

好吧,我花了很多时间才弄清楚这一点,所以我希望它也能帮助其他人。

/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

这就是为什么您不能将其用作普通用户,而只能用作您在帖子中提到的根用户。

如您所见,允许的组称为两个 FrameBuffers 的video
将您的用户添加到视频组应该可以解决您的问题:

usermod -a -G video username

我在尝试使用 pygame 作为永久显示器时遇到了同样的问题。

我决定让 pi 在启动时自动启动,它可以以 root 身份启动 pygame 代码。

要激活自动启动,请添加行以启动您的代码

/etc/rc.local

exit 0线上方。

例如(我在'/opt/pygame_prototype/pg.py'中有代码)

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

然后在启动时,pi 不会 go 登录,而是启动 pygame 程序。

注意:在没有虚拟环境的情况下使用“apt get”安装 pygame,较新的 pip 安装版本失败了。

暂无
暂无

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

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