मैं एक SDL ऐप को (रूट के रूप में नहीं) कैसे कंसोल का उपयोग करने देता हूं


14

मैं कंसोल पर ग्राफिक्स को प्रदर्शित करने के लिए एसडीएल-आधारित प्रोग्राम का उपयोग करना चाहता हूं, कंसोल से लॉग ऑन किए बिना, और प्रोग्राम को रूट के बिना चलाना। उदाहरण के लिए, मैं इसे ssh के माध्यम से चलाने में सक्षम होना चाहता हूं। लक्ष्य ओएस रास्पबियन है।

इस समस्या का वर्णन करने के लिए अजगर में एक छोटा उदाहरण दिया गया है:

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

यह काम करता है (रन पूरा करने के लिए, अपवाद नहीं फेंकता है) अगर मैं इसे कंसोल से चलाता हूं, और यह ssh के माध्यम से काम करता है अगर मैं इसे रूट पर चलाता हूं।

मैंने जाँच की है कि मेरा उपयोगकर्ता ऑडियो और वीडियो समूहों में है।

मैंने यह देखने के लिए स्ट्रेस का उपयोग किया है कि इसे कंसोल से चलाने के बीच क्या अलग है (जो काम करता है), इसे ssh के माध्यम से रूट के रूप में चलाना (यह भी काम करता है), और इसे ssh (काम नहीं करता है) के माध्यम से एक नियमित उपयोगकर्ता के रूप में चलाना।

पहला अंतर यह था कि मेरे उपयोगकर्ता के पास / dev / tty0 तक पहुँचने की अनुमति नहीं थी। मैंने एक नया समूह (tty0) बनाया, उस समूह में अपने उपयोगकर्ता को रखा, और उस समूह को / dev / tty0 तक पहुँच प्रदान करने के लिए एक udv नियम जोड़ा।

इस ioctl कॉल पर स्ट्रेस आउटपुट डाइवर्ज होता है - विफलता यहां दिखाई देती है; ioctl 0 तब देता है जब प्रोग्राम कंसोल से चलाया जाता है या ssh से रूट के रूप में चलाया जाता है:

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

(पते भी अलग-अलग हैं, लेकिन यह महत्वपूर्ण नहीं है।)

यह देखते हुए कि मेरा कार्यक्रम तब काम करता है जब यह रूट के रूप में चलता है, मुझे लगता है कि इसका मतलब है कि मुझे एक अनुमति समस्या है। मैं अपने उपयोगकर्ता को कंसोल पर लॉग ऑन किए बिना (और रूट के रूप में चलने के बिना) इस कार्यक्रम को चलाने में सक्षम होने के लिए आवश्यक अनुमति कैसे दे सकता हूं?


आपके फ़्रेमबफ़र डिवाइस पर स्वामित्व / अनुमतियां क्या हैं?
बांद्रमी

इसके अलावा / dev / tty को आमतौर पर लिखने के लिए कंसोल समूह में सदस्यता की आवश्यकता होती है।
बांद्रमी

ajclarkson.co.uk/blog/pygame-no-root एक समाधान की तरह दिखता है।
आर्थर २ इ ०५

जवाबों:


3

मेरा उद्देश्य मूल पोस्टर के समान ही था, लेकिन एक अंतर के साथ: मुझे एसडीएल एप्लिकेशन को एक सिस्टमड डेमॉन के रूप में चलाने की आवश्यकता थी। मेरी लिनक्स मशीन रास्पबेरी पाई 3 है और ऑपरेटिंग सिस्टम रास्पियन जेसी है। आरपीआई से जुड़ा कोई कीबोर्ड या माउस नहीं है। मैं एसएसएच का उपयोग करके इसे जोड़ता हूं। मेरा SDL ऐप वास्तव में Pygame आधारित ऐप है। मैंने SDL_VIDEODRIVER पर्यावरण चर के माध्यम से "fbcon" फ्रेम बफ़र ड्राइवर का उपयोग करने के लिए pygame / SDL सेट किया। मेरा systemd --versionआउटपुट है:

systemd 215 + PAM + AUDIT + SELINUX + IMA + SYSVINIT + LIBCRYPTSETUP + GCRYPT + ACL + XZ -SECCOMP -APPARMOR

मेरा pygame पैकेज संस्करण है: ( aptitude show python-pygame):

1.9.2 ~ पूर्व ~ r3348-2 ~ bpo8 + rpi1

मेरा libSDL 1.2 संस्करण है: ( aptitude show libsdl1.2debian- आपके मशीन पैकेज का नाम अलग हो सकता है):

1.2.15-10 + rpi1

विधि

  1. UDude के उत्तर में वर्णित के रूप में / dev / tty और / dev / fb0 फ़ाइलों के लिए अनुमतियाँ सेट करें। मुझे पता चला कि रास्पियन जेसी में डेव / कंसोल अनुमति परिवर्तन आवश्यक नहीं हैं।
  2. इन लाइनों को अपने डेमन के .service फ़ाइल के [सेवा] अनुभाग में जोड़ें:

    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
    

    यदि कोई दिलचस्पी रखता है, तो यहां पूरी pyscopefb.service फ़ाइल है जिसका मैंने उपयोग किया है:

    [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. कमांड प्रॉम्प्ट में इन आदेशों को जारी करें (मुझे लगता है कि pyscopefb.service फ़ाइल पहले से ही उस सही स्थान पर रखी गई है जहाँ systemd इसे पा सकता है):

    sudo systemctl daemon-reload
    sudo systemctl start pyscopefb
    

यह मेरे लिए काम कर रहा है। कृपया ध्यान दें कि मैंने परीक्षण नहीं किया कि pygame एप्लिकेशन कीबोर्ड और माउस ईवेंट प्राप्त करने में सक्षम है या नहीं।

बक्शीश

मुझे दूसरी 2 समस्याओं को भी हल करना था जो रूचि की हो सकती हैं

  1. फ़्रेमबफ़र ग्राफ़िक्स के साथ स्क्रीन के निचले भाग में ब्लिंकिंग टेक्स्ट कर्सर था। इसे हल करने के लिए, मैंने अपने आवेदन में निम्नलिखित पायथन कोड जोड़ा, जो Pygame / SDL इनिशियलाइज़ेशन से पहले मेरे ऐप में चलता है:

    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. रास्पबेरी पाई के एचडीएमआई आउटपुट से जुड़ी लगभग 10 मिनट की स्क्रीन के बाद काला हो गया (लेकिन संचालित नहीं हुआ) और मेरे ग्राफिक्स ने प्रदर्शित नहीं किया, हालांकि Pygame ने कोई त्रुटि नहीं बताई। यह एक बिजली की बचत की सुविधा है। इसे अक्षम करने के लिए, मैंने निम्नलिखित पायथन कोड जोड़ा, जो Pygame / SDL इनिशियलाइज़ेशन से पहले भी चलता है:

    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
यह मेरे पाई से जुड़े एक कीबोर्ड के बिना pygame शुरू करने को पूरा करने के लिए मेरे लिए बेहद मददगार था, इसलिए धन्यवाद! मैं इस बात का उल्लेख करना चाहता था कि मुझे यह बहुत आसान लगा कि मैं pygame को चलाऊं /dev/tty7और ExecStartPre=/bin/chvt 7कर्सर से बचने के लिए अंक जारी करूं , और इसमें एगेटी से न टकराने का बोनस है जो tty1-tty6 पर डिफ़ॉल्ट रूप से चलता है।
dctucker

2

यद्यपि आप सवाल थोड़ा अस्पष्ट है (कंसोल से क्या अभिप्राय है), मैं सबसे सामान्य मामलों के लिए उत्तर देने का प्रयास करूंगा: / dev / कंसोल, / dev / tty, / dev / fb0 ... इसे उन डिवाइसों के लिए अनुकूलित करें जिनकी आपको आवश्यकता है। हम मानते हैं कि उपयोगकर्ता नाम "myuser" है।

डिवाइस की अनुमतियों को देखें (यह 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

कार्यवाही करना

/ Dev / कंसोल

समूह "रूट" है, लेकिन कोई समूह एक्सेस की अनुमति नहीं है। मुझे रूट ग्रुप में सिर्फ परमिशन जोड़ना पसंद नहीं है, इसलिए मैं एक ग्रुप बनाकर फाइल को चेंज कर देता हूं और परमिशन बदल देता हूं

$ 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> 

आप उपर्युक्त सभी समूहों में अपने उपयोगकर्ता को जोड़ने के लिए usermod कमांड का उपयोग कर सकते हैं , वह भी, यदि आपकी आवश्यकता है।


-1

मेरे हाल के अनुभव से, अपने tty डिवाइस को अनुमति देने के अलावा (जैसा कि पहले उल्लेख किया गया है) आपको 2 अतिरिक्त चीजें करने की आवश्यकता है:

  • निष्पादन योग्य के लिए cap_sys_tty_config क्षमता प्रदान करना। यदि आप अजगर कार्यक्रम का उपयोग कर रहे हैं, तो आप इसे पसंद कर सकते हैं setcap cap_sys_tty_config+eip /usr/bin/python3.5(अपने साथ अजगर के लिए पथ का विकल्प)। बेशक, ध्यान रखें कि आप किसी भी अजगर स्क्रिप्ट के लिए यह क्षमता प्रदान कर रहे हैं।
  • नए वर्चुअल टर्मिनल में प्रक्रिया चलाना, जैसे कि ओपनवेट का उपयोग करना: openvt ./your_script.py
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.