Skip to content

Instantly share code, notes, and snippets.

@junkblocker
Forked from digitaltrails/notify-desktop
Last active May 19, 2024 17:19
Show Gist options
  • Save junkblocker/2a5668d57422fb53e60e9e3f0a1d9e91 to your computer and use it in GitHub Desktop.
Save junkblocker/2a5668d57422fb53e60e9e3f0a1d9e91 to your computer and use it in GitHub Desktop.
notify-desktop - linux find and notify desktop session
#!/usr/bin/env bash
# Provides a way for a root process to perform a notify send for each
# of the local desktop users on this machine.
#
# Intended for use by cron and timer jobs. Arguments are passed straight
# to notify send. Falls back to using wall. Care must be taken to
# avoid using this script in any potential fast loops.
#
# X11 users should already have a dbus address socket at /run/user/<userid>/bus
# and this script should work without requiring any initialisation. Should
# this not be the case, X11 users could initilise a proxy as per the wayland
# instructions below.
#
# Due to stricter security requirments Wayland lacks an dbus socket
# accessable to root. Wayland users will need to run a proxy to
# provide root with the necessary socket. Each user can must add
# the following to a Wayland session startup script:
#
# notify-desktop --create-dbus-proxy
#
# That will start xdg-dbus-proxy process and make a socket available under:
# /run/user/<userid>/proxy_dbus_<desktop_sessionid>
#
# Once there is a listening socket, any root script or job can pass
# messages using the syntax of notify-send (man notify-send).
#
# Example messages
# notify-desktop -a Daily-backup -t 0 -i dialog-information.png "Backup completed without error"
# notify-desktop -a Remote-rsync -t 6000 -i dialog-warning.png "Remote host not currently on the network"
# notify-desktop -a Daily-backup -t 0 -i dialog-error.png "Error running backup, please consult journalctl"
# notify-desktop -a OS-Upgrade -t 0 -i dialog-warning.png "Update in progress, do not shutdown until further completion notice."
#
# Warnings:
# 1) There has only been limited testing on wayland
# 2) There has only been no testing for multiple GUI sessions on one desktop
#
if [[ ${1} == "--create-dbus-proxy" ]]; then
if [[ -n "${DBUS_SESSION_BUS_ADDRESS}" ]]; then
sessionid=$(cat /proc/self/sessionid)
xdg-dbus-proxy "${DBUS_SESSION_BUS_ADDRESS:-}" "/run/user/$(id -u)/proxy_dbus_${sessionid:-}" &
exit 0
else
echo "ERROR: no value for DBUS_SESSION_BUS_ADDRESS environment variable - not a wayland/X11 session?"
exit 1
fi
fi
find_desktop_session() {
for sessionid in $(loginctl list-sessions --no-legend | awk '{ print $1 }'); do
loginctl show-session -p Id -p Name -p User -p State -p Type -p Remote -p Display "${sessionid:-}" \
| awk -F= '
/[A-Za-z]+/ { val[$1] = $2; }
END {
if (val["Remote"] == "no" &&
val["State"] == "active" &&
(val["Type"] == "x11" || val["Type"] == "wayland")) {
print val["Name"], val["User"], val["Id"];
}
}'
done
}
count=0
while read -r -a desktop_info; do
if [[ ${#desktop_info[@]} -eq 3 ]]; then
desktop_user=${desktop_info[0]}
desktop_id=${desktop_info[1]}
desktop_sessionid=${desktop_info[2]}
proxy_bus_socket="/run/user/${desktop_id}/proxy_dbus_${desktop_sessionid}"
if [ -S "${proxy_bus_socket:-}" ]; then
bus_address="${proxy_bus_socket}"
else
bus_address="/run/user/${desktop_id}/bus"
fi
sudo -u "${desktop_user:-}" DBUS_SESSION_BUS_ADDRESS="unix:path=${bus_address}" notify-send "$@"
count=$((count + 1))
fi
done <<<"$(find_desktop_session)"
# If no one has been notified fall back to wall
if [[ ${count} -eq 0 ]]; then
echo "$@" | wall
fi
# Don't want this to cause a job to stop
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment