시스템 설정 이벤트에서 디스플레이 관련 명령어 실행

시스템 설정 이벤트에서 디스플레이 관련 명령어 실행

업스트림을 공유하고 싶은 systemd/udev 설정을 개발 중이지만 해킹되지 않은 방식으로 작동하도록 할 수는 없습니다. 기본적으로 저는 이 스크립트를 systemd 서비스의 실행자로 사용합니다.

      ICON="somepath/dslr-camera-white.png"

      function on-display() {
          local sdisplay=$(echo $XDG_SESSION_TYPE)
          if [ "$sdisplay" == "wayland" ]; then
          local display=":$(echo $WAYLAND_DISPLAY)"
          else
          local display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
          fi
          
          local user=$(who | grep '('$display')' | awk '{print $1}' | head -n 1)

          local uid=$(id -u $user)

          sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus "$@"
      }

      cleanup() {
          on-display notify-send -i $ICON "Disconnected" "The DSLR Camera has been turned off." --app-name="DSLR Webcam"
          trap - SIGTERM && kill -- -$$
      }

      trap cleanup SIGINT SIGTERM EXIT

      on-display notify-send -i $ICON "Connected" "The DSLR Camera has been turned on and it is ready to use." --app-name="DSLR Webcam"
      on-display yad --window-icon=$ICON --image=$ICON --no-buttons --title="DSLR Webcam" --notification --listen &

      output=$(v4l2-ctl --list-devices)
      line=$(echo "$output" | grep "Virtual Camera")
      vdevice=$(echo "$output" | sed -n "/$line/{n;s/^\t\+//p;}")
      gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 $vdevice

서비스의 요점은 특정 gphoto2 지원 카메라가 연결될 때 udev 규칙에 의해 시작되는 것이므로 다음과 같은 udev 규칙이 있습니다.

ACTION=="add", ATTR{idVendor}=="04a9", ATTR{idProduct}=="3218", RUN+="systemctl start dslr-webcam.service"
ACTION=="remove", ATTR{idVendor}=="04a9", ATTR{idProduct}=="3218", RUN+="systemctl stop dslr-webcam.service"

지금까지 systemd 서비스 사용에 대한 대안을 읽었으므로 "좋아요"입니다 RUN. 하지만 어쨌든... 여기서 질문은 구체적으로 yad.

yad는 CLI에서 대화 상자를 표시할 수 있는 프로그램인데, 카메라가 활성화될 때 시스템 아이콘이 표시되기를 원했기 때문에 시스템 아이콘을 만드는 데 사용했습니다.

질문

와 달리 notify-send일부 일반 소켓에서 작동할 수 있으며 작동하려면 yad적절한 설정이 필요합니다 . XAUTHORITY그렇지 않으면 . cannot open display: :0내 경우 해키 솔루션은 SDDM(디스플레이 관리자)을 사용하고 있으므로 /tmp스크립트에 추가할 수 있도록 디렉토리에 상주하므로 올바른 Xauthority로 간단히 설정하는 것이었습니다.

XAUTHORITY=$(ls /tmp/xauth*)

그런 다음 효과가 있었지만... 끔찍했습니다. 많은 가정을 했고 실제로 전체 on-display기능도 나쁜 생각처럼 보였습니다. 이것을 다른 시스템으로 가져가면 적절한 Xauthority가 셀 수 없이 많은 장소에 있을 수 있고 아직 Wayland를 시도해 본 적도 없기 때문에 아마도 작동하지 않을 것입니다(나중에 남겨두겠습니다).

무엇에 대해xauth

어떻게든 올바른 Xauthority를 ​​검색할 수 있을 거라 생각했는데 xauth그렇지 않은 것 같네요... 이 스크립트는 시스템 서비스이므로 xauth info돌아가서 Authority file: /root/.xauthWV7OfU올바른 사용자로 실행했지만 sudo -u $user xauth info작동 Authority file: /home/myuser/.Xauthority하지 않습니다. 역할은 주어지면 부여됩니다 yad. 올바른 역할은 XAUTHORITY디스플레이 관리자에 의해 설정되므로 하위 프로세스에서만 가져올 수 있는 것 같습니다.

나는 또한 this에서 제공하는 모든 방법을 시도했습니다.답변, 그런데 첫 번째는 XAUTHORITY실제로 시스템 환경이 아니기 때문에 작동하지 않고, 두 번째는(언급된 문제 외에) 작동하지 않고, xauth 파일이 위치해 있다고 하는데 /run/sddm/xauth_KvyuHd사용하려고 하면 안 됩니다. 작동하므로 xauth 파일과 다릅니다./tmp/xauth_FzoQqz

이전 질문과 같은 질문에서 나왔습니다.이것이 방법은 효과가 있는 것 같지만 이식성이 얼마나 좋은지는 모르겠습니다. 그리고 여전히 진부해 보입니다.


사용자 서비스로 실행

아마도 이것은 사용자로 실행되는 것을 방지하는 스크립트에 아무것도 없기 때문에 가장 유망한 것일 수 있습니다(그것도 제거했습니다 on-display). 나는 이것을 시도했고 카메라가 연결되어 있고 실행하면 systemctl --user start dslr-webcam.service예상대로 작동합니다( 포함 yad), 이제 규칙에 대한 질문이 있습니다 udev. 포함한 여러 곳을 검색해봤는데여기, 그러나 규칙에서 시스템 사용자 서비스를 실행하는 방법을 찾을 수 없습니다 . 어떤 사용자를 사용할지 udev어떻게 알 수 있습니까 ?udev

답변1

대신 udev 규칙에서 직접 사용자 서비스를 실행하지 마십시오.udev가 장치에 특정 사용자 서비스가 필요함을 systemd에 알립니다.달리기.

이와 같이 TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="dslr-webcam.service":

ACTION=="add", ATTR{idVendor}=="04a9", ATTR{idProduct}=="3218". TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="dslr-webcam.service"
ACTION=="remove", ATTR{idVendor}=="04a9", ATTR{idProduct}=="3218", TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="dslr-webcam.service"

GUI 액세스가 필요 하므로 자체적으로 및 dslr-webcam.service로 선언해야 합니다 . 이러한 방식으로 선언되면 서비스는 자동으로 올바른 DISPLAY 및 XAUTHORITY 변수를 얻어야 합니다.BindsTo=graphical-session.targetAfter=graphical-session.target

그런데, 당신의 아이디어를 공유해 주셔서 감사합니다. 그것은 나에게 매우 유사한 것을 만들 수 있는 영감을 주었습니다...

관련 정보