Ich möchte ein SDL-basiertes Programm verwenden, um Grafiken auf der Konsole anzuzeigen, ohne mich von der Konsole aus anmelden zu müssen und ohne das Programm als Root auszuführen. Zum Beispiel möchte ich es über ssh ausführen können. Das Ziel-Betriebssystem ist Raspbian.
Hier ist ein kurzes Beispiel in Python, um das Problem zu veranschaulichen:
import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"
Dies funktioniert (läuft bis zum Abschluss, wirft keine Ausnahmen), wenn ich es von der Konsole aus starte, und es funktioniert über ssh, wenn ich es als root starte.
Ich habe überprüft, ob sich mein Benutzer in den Audio- und Videogruppen befindet.
Ich habe strace benutzt, um zu sehen, was anders ist, als es von der Konsole aus (was funktioniert), als root über ssh (funktioniert auch) und als normaler Benutzer über ssh (funktioniert nicht) auszuführen.
Der erste Unterschied war, dass mein Benutzer keine Zugriffsberechtigung für / dev / tty0 hatte. Ich habe eine neue Gruppe (tty0) erstellt, meinen Benutzer in diese Gruppe aufgenommen und eine udev-Regel hinzugefügt, um dieser Gruppe Zugriff auf / dev / tty0 zu gewähren.
Die Ausgabe von strace weicht bei diesem ioctl-Aufruf ab - der Fehler wird hier angezeigt. ioctl gibt 0 zurück, wenn das Programm von der Konsole oder von ssh als root ausgeführt wird:
open("/dev/tty", O_RDWR) = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8) = -1 EINVAL (Invalid argument)
(Die Adressen unterscheiden sich auch, aber das ist nicht wichtig.)
Angesichts der Tatsache, dass mein Programm als Root ausgeführt wird, bedeutet dies, dass ich ein Berechtigungsproblem habe. Wie erteile ich meinem Benutzer die erforderlichen Berechtigungen, um dieses Programm ausführen zu können, ohne sich an der Konsole anzumelden (und ohne als Root ausgeführt zu werden)?
quelle
Antworten:
Mein Ziel war das gleiche wie beim ursprünglichen Poster, aber mit einem Unterschied: Ich musste die SDL-Anwendung als systemd-Daemon ausführen. Mein Linux-Rechner ist Raspberry Pi 3 und das Betriebssystem ist Raspbian Jessie. Es ist keine Tastatur oder Maus mit RPi verbunden. Ich verbinde mich mit SSH. Meine SDL-App ist eigentlich eine Pygame- basierte App. Ich habe pygame / SDL so eingestellt, dass der Framebuffer-Treiber "fbcon" über die Umgebungsvariable SDL_VIDEODRIVER verwendet wird. Meine
systemd --version
Ausgabe ist:Meine Pygame-Paketversion ist: (
aptitude show python-pygame
):Meine libSDL 1.2 Version ist: (
aptitude show libsdl1.2debian
- auf Ihrem Rechner kann der Paketname unterschiedlich sein):Das Rezept
Fügen Sie diese Zeilen zum Abschnitt [Service] der .service-Datei Ihres Daemons hinzu:
Falls jemand Interesse hat, hier ist die vollständige pyscopefb.service-Datei, die ich verwendet habe:
Geben Sie diese Befehle in der Eingabeaufforderung ein (ich nehme an, dass die Datei pyscopefb.service bereits an der richtigen Stelle abgelegt ist, an der systemd sie finden kann):
Das funktioniert für mich. Bitte beachten Sie, dass ich nicht getestet habe, ob die Pygame-Anwendung Tastatur- und Mausereignisse empfangen kann oder nicht.
Bonus
Ich musste auch zwei andere Probleme lösen, die ebenfalls von Interesse sein könnten
Es gab einen blinkenden Textcursor am unteren Rand des Bildschirms mit Framebuffer-Grafiken. Um dies zu beheben, habe ich meiner Anwendung den folgenden Python-Code hinzugefügt, der in meiner Anwendung vor der Pygame / SDL-Initialisierung ausgeführt wird:
Nach ungefähr 10 Minuten wurde der an den HDMI-Ausgang von Raspberry Pi angeschlossene Bildschirm schwarz (aber nicht ausgeschaltet) und meine Grafiken wurden nicht angezeigt, obwohl Pygame keine Fehler meldete. Dies stellte sich als Stromsparfunktion heraus. Um dies zu deaktivieren, habe ich den folgenden Python-Code hinzugefügt, der auch vor der Pygame / SDL-Initialisierung ausgeführt wird:
quelle
/dev/tty7
und ein auszugebenExecStartPre=/bin/chvt 7
, um die Cursor-Sache zu vermeiden, und dass es den Bonus hat, nicht mit agetty zu kollidieren, das standardmäßig auf tty1 – tty6 läuft.Obwohl Ihre Frage etwas mehrdeutig ist (was mit Konsole gemeint ist), werde ich versuchen, die häufigsten Fälle zu beantworten: / dev / console, / dev / tty, / dev / fb0 ... passen Sie dies an die Geräte an, die Sie benötigen. Wir gehen davon aus, dass der Benutzername "myuser" ist.
Schauen Sie sich die Berechtigungen des Geräts an (dies ist Ubuntu 15.04)
Handeln Sie
/ dev / console
Die Gruppe ist "root", es ist jedoch kein Gruppenzugriff zulässig. Ich mag es nicht, der Stammgruppe nur Berechtigungen hinzuzufügen, sondern erstelle stattdessen eine Gruppe, chgrp die Datei und ändere die Berechtigungen
/ dev / tty
/ dev / fb0
Sie können den Befehl usermod verwenden , um Ihren Benutzer auch allen oben genannten Gruppen hinzuzufügen, falls dies erforderlich ist.
quelle
Nach meinen jüngsten Erfahrungen müssen Sie neben der Erteilung der Erlaubnis für Ihr tty-Gerät (wie oben erwähnt) zwei weitere Dinge tun:
setcap cap_sys_tty_config+eip /usr/bin/python3.5
folgt machen (ersetzen Sie den Pfad für Python durch Ihren). Beachten Sie natürlich, dass Sie diese Funktion für jedes Python-Skript gewähren.openvt ./your_script.py
quelle