I am trying to get a notification when pluging in a USB device, for this I use a udev rule to track the moment it is pluged and from there I launch a script. The idea on the script was to use what it is explained in the link.
but when trying this:
pids=`pgrep -u $user gnome-panel`
I found that gnome-panel is not there. Googled this work arround and I found quite few people complaining that this work arround is no longer working. So I did a bit of research on the subject and came up with this (notify-plugin2.sh):
#!/bin/bash
DBUS_SESSION_BUS_ADDRESS=$(cat /home/user/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-0 | grep DBUS_SESSION_BUS_ADDRESS= | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//')
su user Test.sh $DBUS_SESSION_BUS_ADDRESS
to get the DBUS_SESSION_BUS_ADDRESS
before switching user to a non root user. This statement, if I am not wrong works, so based on the code from the link above I made this other script (Test.sh
)
#!/bin/sh
user=`whoami`
title="Test"
timeout=30000
icon="~/Pictures/PicturesForPwrPoint/Pluged.jpg"
DBUS_SESSION_BUS_ADDRESS=$1
echo $DBUS_SESSION_BUS_ADDRESS
DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS \ notify-send -u low -t $timeout -i "$icon" "$title"
For what I can see on the other code, the only problem was getting the DBUS_SESSION_BUS_ADDRESS
, and if I am not wrong, with this I can have it.
So my question is, why there isn't a fancy pop-up message on my screen when launching?
sudo sh notify-plugin2.sh
Combining tomy's answer with hongo's answer to another question elegantly solves the issue for me.
function notify-send() {
#Detect the name of the display in use
local display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
#Detect the user using such display
local user=$(who | grep '('$display')' | awk '{print $1}' | head -n 1)
#Detect the id of the user
local uid=$(id -u $user)
sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send "$@"
}
That function can be used as-is in any script running as root
, as a drop-in replacement for the notify-send
command.
To send desktop notification from a background script running as root
(replace X_user and X_userid with the user and userid running X respectively):
sudo -u X_user DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/X_userid/bus notify-send 'Hello world!' 'This is an example notification.'
This was taken from: https://wiki.archlinux.org/index.php/Desktop_notifications
The notification service has been changed for ubuntu 14.04
.
Its called now smth like org.freedesktop.Notifications.service
You can check here for more information about Notification On Screen Display
possibilities.
Also you can use following command line to send your own messages
user@machine ~$ notify-send “Text of message”
Just update your script which is being launched by udev
to use it.
To workaround the problem realted to running the notify-send
command as root.
Try to run is as your normal user, i.e.
su <YOURUSER> -c 'notify-send “Text of message”'
I tried Fabio A's solution. However, I noticed that it was not working consistently on my Arch Linux installation. Problem was that who
did not display the port number for the tty1 session:
$ who
john tty1 2021-03-21 09:02
I am running i3 via exec startx
on my Arch installation. On the other hand, I noticed that the output of who
on a Ubuntu desktop installation looked completely different. Here, the display number is shown:
$ who
john :0 2021-03-21 09:49 (:0)
So I was looking for another solution to get rid of the who
command. I found that ps aux
contains this useful entry which contains both the display number as well as the username:
$ ps aux | grep xinit
john 785 763 0 19:14 tty1 S+ 0:00 xinit /home/john/.xinitrc -- /etc/X11/xinit/xserverrc :0 vt1 -keeptty -auth /tmp/serverauth.gGcqw2rJXG
This is the new script I wrote:
#/bin/bash
xinit_pid=$(pgrep xinit)
if [ -n "xinit_pid" ]; then
xinit_ps=$(ps --no-headers -f $xinit_pid | head -n 1)
display=$(echo "$xinit_ps" | grep -Po " :[0-9]+ " | tr -d " ")
user=$(echo "$xinit_ps" | cut -d " " -f 1)
uid=$(id -u $user)
echo "Display environment: $display $user $uid"
sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send "$@"
else
echo "Warning: Could not find xinit process!"
fi
Any other script can call this script via:
bash /opt/notify-send-helper Title Message -t 5000
On a side note: I am using dunstify
instead of notify-send
. dunstify
has the advantage of being able to assign IDs to a notification: Only the newest notification for the same ID is shown.
EDIT: I used to query the process "Xorg". However, strangely enough I noticed on one machine that this process was run as root. I switched to the "xinit" process instead which works just the same but seems to be always run by the normal user.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With