Bir SDL uygulamasının (root olarak çalışmıyor) konsolu kullanmasına nasıl izin verebilirim?


14

Konsolda grafik görüntülemek, konsoldan oturum açmak zorunda kalmadan ve programı kök olarak çalıştırmadan SDL tabanlı bir program kullanmak istiyorum. Örneğin, ssh ile çalıştırabilmek istiyorum. Hedef işletim sistemi ahududu.

İşte sorunu göstermek için python'da kısa bir örnek:

import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"

Konsoldan çalıştırırsam bu çalışır (tamamlamaya çalışır, istisnalar atmaz) ve kök olarak çalıştırırsam ssh ile çalışır.

Kullanıcımın ses ve video gruplarında olduğunu kontrol ettim.

Konsolu çalıştırmak (hangi çalışır), ssh üzerinden root olarak çalıştırmak (ayrıca çalışır) ve ssh üzerinden normal bir kullanıcı olarak çalıştırmak (çalışmıyor) arasındaki farkı görmek için strace kullandım.

İlk fark, kullanıcımın / dev / tty0 erişimine sahip olmamasıydı. Yeni bir grup (tty0) oluşturdum, kullanıcımı bu gruba koydum ve bu gruba / dev / tty0'a erişim vermek için bir udev kuralı ekledim.

Strace çıkışı bu ioctl çağrısında ayrılır - hata burada gösterilir; Program konsoldan çalıştırıldığında veya ssh'den root olarak çalıştırıldığında ioctl 0 değerini döndürür:

open("/dev/tty", O_RDWR)                = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8)       = -1 EINVAL (Invalid argument)

(Adresler de farklıdır, ancak bu önemli değildir.)

Programımın kök olarak çalıştığı göz önüne alındığında, bunun bir izin sorunum olduğu anlamına geldiğini düşünüyorum. Konsolda oturum açmadan (ve root olarak çalıştırmadan) bu programı çalıştırabilmek için kullanıcıma gerekli izinleri nasıl verebilirim?


Framebuffer cihazınızdaki sahiplik / izinler nelerdir?
Bandrami

Ayrıca / dev / tty genellikle yazmak için konsol grubuna üyelik gerektirir.
Bandrami

ajclarkson.co.uk/blog/pygame-no-root bir çözüm gibi görünüyor.
Arthur2e5

Yanıtlar:


3

Amacım orijinal posterinkiyle aynıydı, ancak bir farkla: SDL uygulamasını sistemd arka plan programı olarak çalıştırmam gerekiyordu. Linux makinem Raspberry Pi 3 ve işletim sistemi Raspbian Jessie. RPi'ye bağlı klavye veya fare yok. SSH kullanarak bağlandım. SDL uygulamam aslında Pygame tabanlı bir uygulamadır. Pygame / SDL'yi SDL_VIDEODRIVER ortam değişkeni üzerinden “fbcon” framebuffer sürücüsünü kullanacak şekilde ayarladım. Çıktım systemd --version:

systemd 215 + PAM + DENETİM + SELINUX + IMA + SYSVINIT + LIBCRYPTSETUP + GCRYPT + ACL + XZ -SECCOMP -APPARMOR

Pygame paketimin sürümü: ( aptitude show python-pygame):

1.9.2 ~ r3348-2 ~ bpo8 + rpi1 pre

Benim libSDL 1.2 sürümü: ( aptitude show libsdl1.2debian- makine paketinizin adı farklı olabilir):

1.2.15-10 + rpi1

Yemek tarifi

  1. / Dev / tty ve / dev / fb0 dosyaları için izinleri UDude yanıtında açıklandığı şekilde ayarlayın. Raspbian Jessie'de / dev / console izin değişikliklerinin gerekli olmadığını keşfettim.
  2. Bu satırları, arka plan programınızın .service dosyanızın [Hizmet] bölümüne ekleyin:

    User=pi #Your limited user name goes here
    StandardInput=tty
    StandardOutput=tty
    TTYPath=/dev/tty2   # I also tried /dev/tty1 and that didn't work for me
    

    İlgilenen biri varsa, işte tam olarak kullandığım pyscopefb.service dosyası:

    [Unit]
    Description=Pyscopefb test service 
    Wants=network-online.target
    After=rsyslog.service
    After=network-online.target
    
    [Service]
    Restart=no
    ExecStart=/home/pi/Soft/Test/pygame/pyscopefb
    ExecStop=/bin/kill -INT $MAINPID
    OOMScoreAdjust=-100
    TimeoutStopSec=10s
    User=pi
    WorkingDirectory=/home/pi/Soft/Test/pygame
    StandardInput=tty
    StandardOutput=tty
    TTYPath=/dev/tty2
    
    [Install]
    WantedBy=multi-user.target
    
  3. Komut isteminde bu komutları verin (pyscopefb.service dosyasının sistemd'in bulabileceği doğru konuma yerleştirildiğini varsayıyorum):

    sudo systemctl daemon-reload
    sudo systemctl start pyscopefb
    

Bu benim için çalışıyor. Pygame uygulamasının klavye ve fare olayları alıp alamayacağını test etmediğimi lütfen unutmayın.

Bonus

Ayrıca ilginizi çekebilecek 2 problem daha çözmek zorunda kaldım

  1. Ekranın altında yanıp sönen metin imleci çerçeve arabellek grafiklerine sahipti. Bunu çözmek için, uygulamama Pygame / SDL başlatmadan önce uygulamamda çalışan aşağıdaki Python kodunu ekledim:

    def _disable_text_cursor_blinking(self):
        command_to_run = ["/usr/bin/sudo", "sh", "-c", "echo 0 > /sys/class/graphics/fbcon/cursor_blink"]
        try:
            output = subprocess32.check_output(command_to_run, universal_newlines = True)
            self._log.info("_disable_text_cursor_blinking succeeded! Output was:\n{output}", output = output)
        except subprocess32.CalledProcessError:
            self._log.failure("_disable_text_cursor_blinking failed!")
            raise
    
  2. Yaklaşık 10 dakika sonra ekran Raspberry Pi'nin HDMI çıkışına bağlı siyah çıktı (ancak kapalı değil) ve grafiklerim görüntülenmedi, ancak Pygame hiçbir hata bildirmedi. Bunun bir güç tasarrufu özelliği olduğu ortaya çıktı. Bunu devre dışı bırakmak için Pygame / SDL başlatma işleminden önce de çalışan aşağıdaki Python kodunu ekledim:

    def _disable_screen_blanking(self):
        command_to_run = ["/usr/bin/setterm", "--blank", "0"]
        try:
            output = subprocess32.check_output(command_to_run, universal_newlines = True)
            self._log.info("_disable_screen_blanking succeeded! Output was:\n{output}", output = output)
        except subprocess32.CalledProcessError:
            self._log.failure("_disable_screen_blanking failed!")
            raise
    

1
Pi'ye bağlı bir klavyeye sahip olmadan oyun oynamaya başlamam için bu bana çok yardımcı oldu, bu yüzden teşekkür ederim! Pygame'i çalıştırmayı /dev/tty7ve ExecStartPre=/bin/chvt 7imleçten kaçınmak için bir tane yayınlamayı yeterince basit bulduğumu belirtmek istedim ve varsayılan olarak tty1 – tty6'da çalışan agetty ile çarpışmama bonusu var.
dctucker

2

Sorunuz biraz belirsiz olsa da (konsol tarafından kastedilen), en yaygın durumlar için cevap vermeye çalışacağım: / dev / console, / dev / tty, / dev / fb0 ... bunu ihtiyacınız olan cihazlara uyarlayın. Kullanıcı adının "kullanıcım" olduğunu varsayıyoruz.

Cihazın izinlerine bakın (bu ubuntu 15.04)

odroid@mbrxu3:~/projects/sc$ ls -l /dev/console
crw------- 1 root root 5, 1 Oct  23  17:49 /dev/console

odroid@mbrxu3:~/projects/sc$ ls -l /dev/tty
crw-rw-rw- 1 root tty 5, 0 Oct 24 17:50 /dev/tty

odroid@mbrxu3:~/projects/sc$ ls -l /dev/fb0 
crw-rw---- 1 root video 29, 0 Jan  1  2000 /dev/fb0

Harekete geç

/ Dev / konsol

grup "root "tur ancak grup erişimine izin verilmez. Sadece kök gruba izinler eklemeyi sevmiyorum, bunun yerine bir grup oluşturup dosyayı chgrp ve izinleri değiştiriyorum

$ sudo addgroup --system console
$ sudo chgrp console /dev/console
$ sudo chmod g+rw /dev/console
$ sudo usermod -a -G console <myuser>     <==== replace <myuser>

/ Dev / TTY

$ sudo usermod -a -G tty <myuser>

/ Dev / fb0

$ sudo usermod -a -G video <myuser> 

Gerekirse, kullanıcıyı yukarıdaki tüm gruplara eklemek için usermod komutunu kullanabilirsiniz .


-1

Son deneyimlerime göre, tty cihazınıza izin vermenin yanı sıra (daha önce belirtildiği gibi) 2 ek şey yapmanız gerekir:

  • yürütülebilir dosya için cap_sys_tty_config yeteneği verilmesi. Python programı kullanıyorsanız, bunu yapabilirsiniz setcap cap_sys_tty_config+eip /usr/bin/python3.5(python'un yolunu sizinkiyle değiştirin). Tabii ki, herhangi bir python betiği için bu özelliği sağladığınızı dikkate alın.
  • işlemi yeni bir sanal terminalde çalıştırma, örneğin openvt kullanma: openvt ./your_script.py
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.