[Mint 18, 19] Using notify-send from a user crontab
Employing the desktop notification mechanism from the command line is a matter of installing libnotify-bin if it isn't yet installed and invoking e.g.
notify-send -u critical -i dialog-warning "summary" "optional text". The "-u critical" keeps the notification on screen until manually closed, the "-i dialog-warning" selects a notification icon as could be chosen from among for example the "Standard Status Icons" section of https://standards.freedesktop.org/icon- ... atest.html
Doing so from a user crontab does not however work: notify-send communicates over the dbus session bus but cron jobs are not part of any graphical user session; are not provided the session bus address of whichever graphical session runs the desktop notifier to be contacted. For Mint 19 and supposedly Ubuntu 18.04 this is easily remedied by manually providing the cron job with the DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus" environment variable but that socket does not in fact exist on Mint 18 and supposedly Ubuntu 16.04.
On Mint 18 the first idea might be to source ~/.dbus/session-bus/$(dbus-uuidgen --get)-0, in which "0" is the X display number as in principle available via loginctl similarly to the below, but when a new session bus launches --- as can happen for any number of reasons --- that file will describe the new bus, not the "main" user session bus that notify-send needs to communicate with the desktop notifier.
In absence of the socket as available from under /run/user for Mint 19 the somewhat unfortunate thing to do is look at the environment of some user graphical session process so as to retrieve DBUS_SESSION_BUS_ADDRESS. Hardcoding e.g. "gnome-session" as said process is the usual thing to do but with logind there's a slightly more elegant method available: get the session identifier for the "Display" session from
loginctl show-user <name>, its "Leader" from
loginctl show-session <session>and its oldest child with
pgrep -o -P <leader>; that oldest child will in normal setups be the desktop session manager and have the correct DBUS_SESSION_BUS_ADDRESS.
As code: you would replace a call of
notify-sendin a user crontab with a call of, e.g., the executable shell script
Code: Select all
#!/bin/sh if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then if [ -z "$LOGNAME" ]; then EUID=$(id -u) else EUID=$(id -u "$LOGNAME") fi [ -z $EUID ] && exit if [ -S /run/user/$EUID/bus ]; then export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$EUID/bus" else SESSION=$(loginctl -p Display show-user "$LOGNAME" | cut -d= -f2) [ -z "$SESSION" ] && exit LEADER=$(loginctl -p Leader show-session "$SESSION" | cut -d= -f2) [ -z $LEADER ] && exit OLDEST=$(pgrep -o -P $LEADER) [ -z $OLDEST ] && exit export $(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$OLDEST/environ) [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && exit fi fi notify-send "$@"
If the user is not in fact logged in this exits gracefully without notifying anything, and it is hoped that this method may survive a few versions.