Quiero usar un programa basado en SDL para mostrar gráficos en la consola, sin tener que iniciar sesión desde la consola y sin ejecutar el programa como root. Por ejemplo, quiero poder ejecutarlo a través de ssh. El sistema operativo de destino es raspbian.
Aquí hay un breve ejemplo en Python para ilustrar el problema:
import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"
Esto funciona (se ejecuta hasta su finalización, no arroja excepciones) si lo ejecuto desde la consola, y funciona a través de ssh si lo ejecuto como root.
Verifiqué que mi usuario está en los grupos de audio y video.
He usado strace para ver qué es diferente entre ejecutarlo desde la consola (que funciona), ejecutarlo como root a través de ssh (también funciona) y ejecutarlo como un usuario normal a través de ssh (no funciona).
La primera diferencia fue que mi usuario no tenía permiso para acceder a / dev / tty0. Creé un nuevo grupo (tty0), puse a mi usuario en ese grupo y agregué una regla udev para darle acceso a ese grupo a / dev / tty0.
La salida strace diverge en esta llamada ioctl: el fallo se muestra aquí; ioctl devuelve 0 cuando el programa se ejecuta desde la consola o se ejecuta desde ssh como root:
open("/dev/tty", O_RDWR) = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8) = -1 EINVAL (Invalid argument)
(Las direcciones también difieren, pero eso no es importante).
Dado que mi programa funciona cuando se ejecuta como root, creo que esto significa que tengo un problema de permisos. ¿Cómo otorgo los permisos necesarios a mi usuario para poder ejecutar este programa sin iniciar sesión en la consola (y sin ejecutar como root)?
fuente
Respuestas:
Mi objetivo era el mismo que el del póster original, pero con una diferencia: necesitaba ejecutar la aplicación SDL como un demonio systemd. Mi máquina Linux es Raspberry Pi 3 y el sistema operativo es Raspbian Jessie. No hay teclado o mouse conectado a RPi. Me conecto a él usando SSH. Mi aplicación SDL es en realidad una aplicación basada en Pygame . Configuré pygame / SDL para usar el controlador de framebuffer "fbcon" a través de la variable de entorno SDL_VIDEODRIVER. Mi
systemd --version
salida es:La versión de mi paquete de pygame es: (
aptitude show python-pygame
):Mi versión de libSDL 1.2 es: (
aptitude show libsdl1.2debian
- en el nombre del paquete de su máquina puede ser diferente):La receta
Agregue estas líneas a la sección [Servicio] del archivo .service de su daemon:
En caso de que alguien esté interesado, aquí está el archivo completo pyscopefb.service que utilicé:
Emita estos comandos en el símbolo del sistema (supongo que el archivo pyscopefb.service ya está ubicado en la ubicación correcta donde systemd puede encontrarlo):
Esto es trabajo para mí. Tenga en cuenta que no probé si la aplicación pygame puede recibir eventos de teclado y mouse o no.
Prima
También tuve que resolver otros 2 problemas que también pueden ser de interés
Había un cursor de texto parpadeante en la parte inferior de la pantalla con gráficos de framebuffer. Para resolver eso, agregué a mi aplicación el siguiente código de Python que se ejecuta en mi aplicación antes de la inicialización de Pygame / SDL:
Después de unos 10 minutos, la pantalla conectada a la salida HDMI de la Raspberry Pi se volvió negra (pero no apagada) y mis gráficos no aparecieron, aunque Pygame no informó errores. Esto resultó ser una función de ahorro de energía. Para deshabilitar eso, agregué el siguiente código de Python que también se ejecuta antes de la inicialización de Pygame / SDL:
fuente
/dev/tty7
y emitir unExecStartPre=/bin/chvt 7
para evitar el cursor, y tiene la ventaja de no chocar con agetty, que se ejecuta por defecto en tty1 – tty6.Aunque su pregunta es ligeramente ambigua (qué se entiende por consola), intentaré responder a los casos más comunes: / dev / console, / dev / tty, / dev / fb0 ... adapte esto a los dispositivos que necesita. Asumimos que el nombre de usuario es "myuser".
Mire los permisos del dispositivo (esto es ubuntu 15.04)
Tomar acción
/ dev / console
el grupo es "root" pero no se permite el acceso al grupo. No me gusta simplemente agregar permisos al grupo raíz, por lo que en su lugar creo un grupo y modifico el archivo y cambio los permisos
/ dev / tty
/ dev / fb0
También puede usar el comando usermod para agregar su usuario a todos los grupos anteriores, si esa es su necesidad.
fuente
Según mi experiencia reciente, además de otorgar permiso a su dispositivo tty (como se mencionó anteriormente) debe hacer 2 cosas adicionales:
setcap cap_sys_tty_config+eip /usr/bin/python3.5
(sustituya la ruta de Python por la suya ). Por supuesto, tenga en cuenta que está otorgando esta capacidad para cualquier script de Python.openvt ./your_script.py
fuente