업스트림을 공유하고 싶은 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.target
After=graphical-session.target
그런데, 당신의 아이디어를 공유해 주셔서 감사합니다. 그것은 나에게 매우 유사한 것을 만들 수 있는 영감을 주었습니다...