장치의 권한 보기(여기서는 ubuntu 15.04)

장치의 권한 보기(여기서는 ubuntu 15.04)

콘솔에 로그인하거나 프로그램을 루트로 실행하지 않고 SDL 기반 프로그램을 사용하여 콘솔에 그래픽을 표시하고 싶습니다. 예를 들어 SSH를 통해 실행할 수 있기를 원합니다. 대상 운영체제는 Raspbian입니다.

다음은 문제를 설명하기 위해 Python으로 작성된 간단한 예입니다.

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

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

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

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

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

strace 출력은 이 ioctl 호출에서 분기됩니다. 여기에는 프로그램이 콘솔이나 ssh에서 루트로 실행될 때 ioctl이 0을 반환합니다.

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

(주소도 다르지만 상관없습니다.)

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

답변1

내 목표는 원본 포스터의 목표와 동일하지만 한 가지 차이점이 있습니다. SDL 애플리케이션을 systemd 데몬으로 실행해야 한다는 것입니다. 내 Linux 컴퓨터는 Raspberry Pi 3이고 운영 체제는 Raspbian Jessie입니다. RPi에 연결된 키보드나 마우스가 없습니다. SSH를 사용하여 연결합니다. 내 SDL 애플리케이션은 실제로파이게임애플리케이션 기반. 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~이전~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
    

이것은 나에게 효과적입니다. 파이게임 응용프로그램이 키보드와 마우스 이벤트를 수신할 수 있는지 여부는 테스트하지 않았다는 점에 유의하십시오.

보너스

또한 흥미로울 수 있는 다른 두 가지 문제도 해결해야 합니다.

  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. 약 10분 후에 Raspberry Pi의 HDMI 출력에 연결된 화면이 검게 변하고(그러나 꺼지지는 않음) Pygame에서 오류가 보고되지 않지만 내 그래픽이 표시되지 않습니다. 이는 절전 기능으로 밝혀졌습니다. 이를 비활성화하기 위해 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
    

답변2

귀하의 질문이 다소 모호하더라도(콘솔이 무엇을 의미합니까?) 가장 일반적인 경우에 답변하려고 노력할 것입니다: /dev/console, /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/콘솔

그룹은 "루트"이지만 그룹 액세스는 허용되지 않습니다. 루트 그룹에 권한만 추가하고 싶지 않아서 그룹을 만들고 파일을 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> 

당신은 그것을 사용할 수 있습니다사용자 모드필요한 경우 명령을 사용하여 위의 모든 그룹에 사용자를 추가할 수도 있습니다.

답변3

최근 경험에 따르면 (위에서 언급한 대로) tty 장치에 권한을 부여하는 것 외에도 다음 두 가지 작업을 수행해야 합니다.

  • 실행 파일에 cap_sys_tty_config 기능을 부여합니다. Python 프로그램을 사용하는 경우 이를 수행할 수 있습니다 setcap cap_sys_tty_config+eip /usr/bin/python3.5(Python의 경로를 사용자의 경로로 바꾸십시오). 물론, 이 기능을 모든 Python 스크립트에 부여한다는 점을 고려하세요.
  • 예를 들어 openvt를 사용하여 새 가상 터미널에서 프로세스를 실행합니다.openvt ./your_script.py

관련 정보