[Mint 18, 19] Using notify-send from a user crontab

Write tutorials for Linux Mint here
More tutorials on https://github.com/orgs/linuxmint/discu ... /tutorials and (archive) on https://community.linuxmint.com/tutorial
Forum rules
Don't add support questions to tutorials; start your own topic in the appropriate sub-forum instead. Before you post read forum rules
Post Reply
rene
Level 20
Level 20
Posts: 12212
Joined: Sun Mar 27, 2016 6:58 pm

[Mint 18, 19] Using notify-send from a user crontab

Post by rene »

Since I've wanted to do so a few times I expect the following may be useful to some. Current as of Mint 18 and 19.

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-send in a user crontab with a call of, e.g., the executable shell script ~/bin/cron-notify,

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 "$@"
Note that the described method, the "else" branch in the above, works on Mint 19 as well as Mint 18 but that we clearly needn't bother if we have the socket available from under /run/user. Also, that the --value parameter to loginctl as available on Mint 19 and allowing to forego cut is not available on Mint 18.

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.
starper
Level 1
Level 1
Posts: 9
Joined: Tue May 18, 2010 4:10 am

Re: [Mint 18, 19] Using notify-send from a user crontab

Post by starper »

Thank you so much kind man!
Script very fine working. Note, in Mint 17.2 & 18.3 this problem was not. But in 19.2 i exhausted until I found your post.
rene
Level 20
Level 20
Posts: 12212
Joined: Sun Mar 27, 2016 6:58 pm

Re: [Mint 18, 19] Using notify-send from a user crontab

Post by rene »

Very good, but do note that if you don't require compatibility with Mint 18.x then you might as well use the 19.x part of that script directly. I.e., use as the cron line something like

Code: Select all

<m> <h> <dom> <mon> <dow> env DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus notify-send foo
And that said, using the original script is of course fine as well....
eddie3000
Level 3
Level 3
Posts: 136
Joined: Mon Jun 24, 2013 2:11 pm

Re: [Mint 18, 19] Using notify-send from a user crontab

Post by eddie3000 »

I found this solution that worked for me. I'm using mint 19.3 cinnamon.

Just pasted these lines into my crontab file:

Code: Select all

DISPLAY=":0.0"
XAUTHORITY="/home/USER/.Xauthority"
XDG_RUNTIME_DIR="/run/user/1000"
Change "USER" to whatever user you want. Notify-send now works in my scripts using cron.

I dunnow why though ;-)
User avatar
ugly
Level 5
Level 5
Posts: 592
Joined: Thu Nov 24, 2016 9:17 pm

Re: [Mint 18, 19] Using notify-send from a user crontab

Post by ugly »

I've used notify-send to set up basic reminders. But instead of using cron, I've used systemd timers.

To do this, I've made a timer file (e.g., /etc/systemd/system/timer-file.timer) and a service file (e.g., /etc/systemd/system/timer-file.service)

The timer file sets up how often to run the script:

Code: Select all

[Unit]
Description=Monthly reminder

[Timer]
OnCalendar=*-*-15 07:00:00
Persistent=true

[Install]
WantedBy=timers.target
And the service file calls the script (e.g., stored at /usr/local/bin/reminder-script)

Code: Select all

[Unit]
Description=Displays a notification to be run monthly on a timer

[Service]
Type=oneshot
ExecStart=/bin/bash /usr/local/bin/reminder-script

[Install]
WantedBy=multi-user.target
Then the script at /usr/local/bin/reminder-script calls notify-send:

Code: Select all

#!/bin/sh
sleep 300
sudo -u $LOGNAME DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send 'Monthly Reminder' 'The text for the reminder'
Then you can enable the timer:

Code: Select all

sudo systemctl enable timer-file.timer
And check the status of the timer: systemctl status timer-file.timer

or check the status of all the timers: systemctl list-timers --all

to check the last time it was run, or how long until the script will run again.
shockedquartz
Level 2
Level 2
Posts: 69
Joined: Tue Dec 17, 2019 3:31 pm

Re: [Mint 18, 19] Using notify-send from a user crontab

Post by shockedquartz »

ugly wrote: Thu Mar 12, 2020 1:31 am I've used notify-send to set up basic reminders. But instead of using cron, I've used systemd timers...
I've tried for a week to get cron to work with notify-send on Mint 19.3 with no luck.
Thank you very much for the fix! :D
User avatar
asobczak
Level 1
Level 1
Posts: 43
Joined: Sun Jun 10, 2012 5:32 pm
Location: Warsaw, Poland

Re: [Mint 18, 19] Using notify-send from a user crontab

Post by asobczak »

eddie3000 wrote: Wed Mar 11, 2020 1:41 pm

Code: Select all

DISPLAY=":0.0"
XAUTHORITY="/home/USER/.Xauthority"
XDG_RUNTIME_DIR="/run/user/1000"
Change "USER" to whatever user you want. Notify-send now works in my scripts using cron.
Works for me!!!!
System: Host: Kernel: 5.4.0-66-generic x86_64 bits: 64 compiler: gcc v: 7.5.0
Desktop: Cinnamon 4.4.8 wm: muffin dm: LightDM Distro: Linux Mint 19.3 Tricia
base: Ubuntu 18.04 bionic
SHUred
Level 2
Level 2
Posts: 60
Joined: Mon Jul 20, 2020 1:50 pm

Re: [Mint 18, 19] Using notify-send from a user crontab

Post by SHUred »

eddie3000 wrote: Wed Mar 11, 2020 1:41 pm I found this solution that worked for me. I'm using mint 19.3 cinnamon.

Just pasted these lines into my crontab file:

Code: Select all

DISPLAY=":0.0"
XAUTHORITY="/home/USER/.Xauthority"
XDG_RUNTIME_DIR="/run/user/1000"
Change "USER" to whatever user you want. Notify-send now works in my scripts using cron.

I dunnow why though ;-)
Also worked for me!!!

Thanks man!
Post Reply

Return to “Tutorials”