Udev Devices Notifications Notify-send – Call Notify-send from a Udev Rule

devicesnotificationsnotify-sendudev

I use Linux Mint 13 MATE, and I'm trying to set up notifications when I plug/unplug devices.

First of all, I found udev-notify package, but unfortunately it almost doesn't work for me: it works for very little time (1-2 minutes), and then, if I connect/disconnect any device, it crashes:

Traceback (most recent call last):
  File "./udev-notify.py", line 319, in <module>
    notification.show()
glib.GError: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name :1.1061 was not provided by any .service files

I haven't found any solution, so I had to remove it. (filed bugreport also)

Surprizingly, there're no similar utilities I've found so far. Then I tried to write udev rules that should match all devices. I have added new file /etc/udev/rules.d/notify.rules :

ACTION=="add",    RUN+="/bin/bash /home/dimon/tmp/device_plug.sh"
ACTION=="remove", RUN+="/bin/bash /home/dimon/tmp/device_unplug.sh"

And two scripts:

device_plug.sh:

#!/bin/bash

export DISPLAY=":0"
notify-send "device plugged"

/usr/bin/play -q /path/to/plug_sound.wav &

device_unplug.sh:

#!/bin/bash

export DISPLAY=":0"
notify-send "device unplugged"

/usr/bin/play -q /path/to/unplug_sound.wav &

It works, but it works very dumb. My questions are:

  1. How to get actual title of the device attached, the same as I can see in lsusb output? Currently, I just got notifications like "plugged" and "unpugged", and I can't find how can I retrieve the name of the device in my udev rule (If I can, then I'd pass it to my script as a parameter)
  2. Currently, too many notifications are activated. Say, when I attach my USB stick, I got about 15 notifications! But, if I run lsusb, attached USB stick is displayed as just single device. So, it seems I should add some more argument to rule filter, but I can't find it out.
  3. Probably there's some better solution for device plug/unplug notifications? Please suggest if you know something.

Best Answer

Well, after many hours of googling and asking on forums, I got it working (it seems). Anyone who wants to get nice visual and/or audio notification when some USB device is plugged/unplugged can install my script, see installation details below.

First of all, answers on my own questions.

1. How to get actual title of the device attached, the same as I can see in lsusb output?

There's no such titles in the kernel (in common case). There is a database file with titles for many pairs vendor_id:product_id, it's usually /usr/share/hwdata/usb.ids file. This database can be updated by /usr/sbin/update-usbids.sh. Thanks to guys from linux.org.ru for that info.

I don't know if there is some special tool for getting device title by pair vendor_id:product_id, so I had to hack a bit with lsusb and grep: for example, lsusb | grep '0458:003a'

2. Currently, too many notifications are activated. Say, when I attach my USB stick, I got about 15 notifications!

I must admit I haven't figured out how to write rule for this, but I found another way I could filter it.

udev allows us to use some substitutions for RUN+="...": say, we can get bus number and device number by $attr{busnum} and $attr{devnum} respectively. Firstly, in my script I store list of attached devices in the special file, so that if script got new "plug" event, and this device's busnum and devnum are already stored in our file, then notification isn't generated. And secondly, these substitutions $attr{busnum} and $attr{devnum} are usually available only for one of the devices from the "series" of events. But anyway, explained algorithm should sort it out in any case.


Current project page: my-udev-notify.

It looks like this:

enter image description here

Installation details.

Tested on Linux Mint 13, I believe it should work on Ubuntu and other Ubuntu's derivatives, and I hope it will work on any *nix system with udev.

  • Go to project page, get sources from there and put them somewhere. There's just one main script in it: my-udev-notify.sh, but archive also contains sounds for plug/unplug notifications, plus some more info, see readme.txt for details.
  • Create file /etc/udev/rules.d/my-udev-notify.rules with the following contents: (don't forget to modify path to your real path where you unpacked my-udev-notify.sh!)

 ACTION=="add",    RUN+="/bin/bash /path/to/my-udev-notify.sh -a add    -p '%p' -b '$attr{busnum}' -d '$attr{devnum}'"
 ACTION=="remove", RUN+="/bin/bash /path/to/my-udev-notify.sh -a remove -p '%p' -b '$attr{busnum}' -d '$attr{devnum}'"

After this, it should work for newly attached devices. That is, if you unplug some device, you won't get notification. But when you plug it back, you will. (yes, for me it works without any udev restarting. If it doesn't for you, try rebooting)

To make it work for all devices, just reboot your system. NOTE that there might be many notifications during first boot (see known issues in the readme.txt). On second boot, there will be no notifications (unless you plug in new device when system is off)

You can customize it (turn on/off visual and sound notifications, or change sounds), check readme.txt in the archive for details.

Related Question