SDL 앱 (루트로 실행되지 않음)이 콘솔을 사용하도록하려면


14

SDL 기반 프로그램을 사용하여 콘솔에서 로그온하지 않고 루트로 프로그램을 실행하지 않고 콘솔에 그래픽을 표시하려고합니다. 예를 들어, ssh를 통해 실행할 수 있기를 원합니다. 대상 OS는 라즈 비안입니다.

다음은 파이썬에서 문제를 설명하는 간단한 예입니다.

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

콘솔에서 실행하면 작동하고 (실행 완료, 예외는 발생하지 않음) 루트로 실행하면 ssh를 통해 작동합니다.

사용자가 오디오 및 비디오 그룹에 있는지 확인했습니다.

나는 strace를 사용하여 콘솔에서 작동하는 것 (작동하는), ssh를 통해 루트로 실행하는 것 (또한 작동하는) 및 ssh를 통해 일반 사용자로 실행하는 것 (작동하지 않는) 사이의 차이점을 확인했습니다.

첫 번째 차이점은 내 사용자에게 / dev / tty0에 액세스 할 수있는 권한이 없다는 것입니다. 새 그룹 (tty0)을 만들고 사용자를 해당 그룹에 넣은 다음 udev 규칙을 추가하여 해당 그룹에 / dev / tty0에 대한 액세스 권한을 부여했습니다.

strace 출력은이 ioctl 호출에서 분기됩니다. 여기서 실패가 표시됩니다. 프로그램이 콘솔에서 실행되거나 ssh에서 루트로 실행될 때 ioctl은 0을 리턴합니다.

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

(주소도 다르지만 중요하지 않습니다.)

루트로 실행될 때 내 프로그램이 작동한다고 가정하면 권한 문제가 있음을 의미합니다. 콘솔에 로그온하지 않고 루트로 실행하지 않고이 프로그램을 실행할 수 있도록 필요한 권한을 사용자에게 부여하려면 어떻게해야합니까?


프레임 버퍼 장치의 소유권 / 권한은 무엇입니까?
Bandrami

또한 / dev / tty는 일반적으로 콘솔 그룹의 구성원 자격을 요구합니다.
Bandrami

ajclarkson.co.uk/blog/pygame-no-root 는 해결책처럼 보입니다.
Arthur2e5

답변:


3

내 목표는 원래 포스터와 같지만 한 가지 차이점이 있습니다. SDL 응용 프로그램을 systemd 데몬으로 실행해야했습니다. 내 Linux 컴퓨터는 Raspberry Pi 3이고 운영 체제는 Raspbian Jessie입니다. RPi에 연결된 키보드 나 마우스가 없습니다. SSH를 사용하여 연결합니다. 내 SDL 앱은 실제로 Pygame 기반 앱입니다. SDL_VIDEODRIVER 환경 변수를 통해 "fbcon"프레임 버퍼 드라이버를 사용하도록 pygame / SDL을 설정했습니다. 내 systemd --version출력은 다음과 같습니다

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

파이 게임 패키지 버전은 다음과 같습니다 : ( aptitude show python-pygame) :

1.9.2 ~ pre ~ r3348-2 ~ bpo8 + rpi1

내 libSDL 1.2 버전은 다음과 같습니다 ( aptitude show libsdl1.2debian-컴퓨터 패키지 이름이 다를 수 있음).

1.2.15-10 + rpi1

조리법

  1. UDude의 답변에 설명 된대로 / dev / tty 및 / dev / fb0 파일에 대한 권한을 설정하십시오. Raspbian Jessie에서는 / dev / console 권한 변경이 필요하지 않다는 것을 알았습니다.
  2. 다음 행을 데몬 .service 파일의 [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
    

이것은 나를 위해 일하고 있습니다. 파이 게임 응용 프로그램이 키보드 및 마우스 이벤트를 수신 할 수 있는지 여부는 테스트하지 않았습니다.

보너스

또한 관심이있을 수있는 또 다른 2 가지 문제를 해결해야했습니다.

  1. 화면 하단에 프레임 버퍼 그래픽으로 깜박이는 텍스트 커서가있었습니다. 이를 해결하기 위해 Pygame / SDL 초기화 전에 내 앱에서 실행되는 다음 Python 코드를 내 응용 프로그램에 추가했습니다.

    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. Pygame은 오류를보고하지 않았지만 약 10 분 후 Raspberry Pi의 HDMI 출력에 연결된 화면이 검은 색으로 바뀌었지만 (전원이 꺼지지는 않음) 그래픽이 표시되지 않았습니다. 이것은 절전 기능으로 판명되었습니다. 이를 비활성화하기 위해 Pygame / SDL 초기화 전에 실행되는 다음 Python 코드를 추가했습니다.

    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
이것은 파이에 키보드를 연결하지 않고도 파이 게임을 시작하는 데 큰 도움이되었습니다. 감사합니다! 파이 게임을 실행 하고 커서를 피하기 위해을 /dev/tty7발행하기 에 충분히 간단하다는 것을 언급하고 ExecStartPre=/bin/chvt 7tty1–tty6에서 기본적으로 실행되는 agetty와 충돌하지 않는 보너스가 있습니다.
dctucker

2

질문이 약간 모호하지만 (콘솔의 의미), 가장 일반적인 경우 / dev / console, / dev / tty, / dev / fb0 ...에 대해 답변하려고 시도합니다. 필요한 장치에 적용하십시오. 사용자 이름이 "myuser"라고 가정합니다.

장치의 권한을 확인하십시오 (이것은 우분투 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 / console

그룹은 "루트"이지만 그룹 액세스는 허용되지 않습니다. 루트 그룹에 권한을 추가하는 것을 좋아하지 않으므로 대신 그룹을 만들고 파일을 chgrp하고 권한을 변경하십시오.

$ 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 사용) : openvt ./your_script.py
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.