HDMI 화면 / TV를 연결 해제 할 때 오디오 출력을 변경 하는 스크립트 를 작성 했습니다. 기본적으로 UDEV를 사용하여 연결 변경 사항을 확인하고 그에 따라 작동합니다.
한 가지를 제외한 모든 것이 잘 작동합니다 notify-send
. 변경에 대해 경고 하는 데 사용할 수 없습니다 . 다음 코드를 사용합니다 ( output
의 래퍼 일뿐입니다 subprocess.check_output
).
output("sudo -u {0} notify-send \"{1}\" \"{2}\"".format(user, title, message))
하지만 전혀 알림이 없습니다.
정말 이상한 점은 hdmi_sound_toggle
(일반 사용자 또는로 sudo
) 실행하면 모든 것이 잘 작동 한다는 것입니다!
그래서 여기서 무엇이 문제가 될 수 있습니까? notify-send
? 보다 알림을 표시하는 더 좋은 방법이 있습니까?
답변
는 notify-send
문제 루트 또는 다른 사용자가 실행하는 스크립트에서 호출 할 때 사용자의 화면에 알림을두고있다.
다음을 사용해야합니다.
output("export DISPLAY=:0; sudo -u {0} notify-send \"{1}\" \"{2}\"".format(user, title, message))
따라서 다음을 사용하십시오.
export DISPLAY=:0
일반적으로 사용자가 디스플레이 :0
에 있지만 확실 who
하게 다음과 같이 명령 을 사용하여 사용자가 어떤 디스플레이에 있는지 확인할 수 있습니다 .
who | grep -m1 ^username.*\( | awk '{print $5}' | sed 's/[(|)]//g'
이것은 이 스크립트 에서 나를 위해 일했습니다 .
참조 : 다른 사용자의 데스크탑에서 루트로 그래픽 프로그램을 시작할 수 있습니까?
답변
나는 모든 X 사용자에게 (루트로) 알리는 일관된 방법을 연구하고 있었고 (넷에서 여러 곳을보고있는) 내 연구는이 방법으로 notify-send를 사용할 수는 있지만 DBUS를 찾기 위해 스크립팅이 필요하다는 것을 보여주었습니다. 세션 정보 및 / 또는 DISPLAY의 사용 및 / 또는 Xauthority 파일 이름 및 위치, 때로는 사람들이 여전히 작동하지 않을 수 있습니다. 요약하면, X 사용자에게 브로드 캐스트 할 수 있도록 귀하의 의지에 따라 알림을 보내려고 시도하면 신뢰할 수없는 것으로 판명 될 것입니다 (특히 향후 어느 시점에서 배포를 업그레이드하거나 변경하는 경우).
그러나 … 내 시스템에서 wall
명령은 매력처럼 작동했으며 사용하기가 매우 간단합니다. 유일한 단점은 메시지를 모든 텍스트 터미널 / 콘솔에도 전달한다는 것입니다. 마음에 들지 않으면 wall
더 좋고 신뢰할 수있는 옵션 일 수 있습니다. 참고 : 사용자 호출 wall
은이어야합니다 root
.
답변
16.04에 Radu의 대답이 효과가없는 것 같습니다. 다른 릴리스로 변경되는 것으로 보이는 DISPLAY 문제와 싸우려고하기보다는 약간 다른 방식으로이 문제를 해결합니다. 두 가지 방법으로 호출되는 단일 스크립트를 만듭니다. udev 규칙은 스크립트를 호출하여 일종의 출력을 명명 된 파이프로 보냅니다. 로그인하면 스크립트도 서비스 모드에서 시작됩니다. 여기서 파이프를 수신하고 원하는 GUI 명령을 실행합니다.
예를 들어, USB 저장 장치가 연결될 때 알림을받는 것을 좋아합니다. 특히, 장치의 경로와 일련 번호 (이상하게 보일 수 있지만 이유가 있음)가 무엇인지 알고 싶습니다. 이 작업을 수행하는 데 사용하는 스크립트는 다음과 같습니다.
#!/bin/bash
# script name: usb-notify.sh
# This script needs to be called at logon with "service" parameter
# This script needs to be called by udev on USB insertion with no parameter
pipe="/tmp/usb-notifications"
if [ "$1" == "service" ]; then
# create the named pipe that will help us trigger events from udev
rm "$pipe"
mkfifo "$pipe"
# This outer while loop ensures that we can process multiple triggers
while true
do
# This inner while loop reads individual trigger events
while read info
do
# run some GUI command. Here, I'm running notify-send
notify-send "USB Inserted" "$(echo -e $info)"
done < "$pipe"
done
else
# Here's where udev triggers our event. If you don't need to pass any arguments
# you could just as easily pass an empty line as a trigger for the service.
[ -e "$pipe" ] && echo "Device: $DEVNAME\\\nSN: $ID_SERIAL_SHORT" > "$pipe"
fi
그런 다음이 스크립트를 두 가지 방법으로 호출해야합니다. 먼저이 스크립트를 호출하려면 udev 규칙을 만들어야합니다. 다음 명령으로이를 수행 할 수 있습니다 (물론 스크립트를 트리거하는 모든 장치를 감시하도록 변경해야 함).
echo 'ACTION=="add",KERNEL=="sd?",RUN+="[path-to-script]/usb-notify.sh"' | sudo tee -a /etc/udev/rules.d/80-USB.rules
둘째, 로그인시 “service”매개 변수를 사용하여이 스크립트를 호출해야합니다. “Startup Applications”프로그램을 열고 “[path-to-your-script] /usb-notify.sh service”를 실행하는 항목을 추가하십시오.
이 스크립트는 udev 이벤트에서 거의 모든 GUI 응용 프로그램을 실행하도록 수정할 수 있습니다. 다른 사용자가 파이프를 보지 못하게하려면 제한적인 권한을 설정해야합니다.
답변
sudo로 호출해야합니까? 문제가 해결 될 수 있습니다.
또한, 나는 내가 필요 발견 DISPLAY=:0
및 XAUTHORITY=/home/<user_name>/.Xauthority
(- 설정이 경우에는 systemd 서비스에서 루트로 실행할 때 작동하도록 설정 Environment=...
).
답변
쉘 명령 대신 pynotify를 사용할 수 있습니다. 매우 간단하며 우분투에서 기본적으로 설치됩니다. 빠른 샘플 :
import pynotify
pynotify.init("Name")
n = pynotify.Notification("Name", "This is a notification")
n.show()