Can UDEV somehow trigger zenity for a logged in user in a session?

0

I would like a zenity dialog popup to ask me if I would like to run a backup, when I attached a specific external drive.

Unfortunately, I am having trouble with the UDEV rule syntax. I've got this rule in /etc/udev/rules.d/test.rules:

ACTION=="add", ATTRS{manufacturer}=="Western Digital", ATTRS{idVendor}=="1058", ATTRS{idProduct}=="1140", RUN+="/usr/local/bin/test.sh"

It's pretty basic, but:

  1. It gets triggered a dozen times in stead of once.
  2. It cannot 'speak' using zenity when test.sh goes sudo -Hu <username> zenity --warning --text="Just some random text for now." because udev is tucked away in the system and cannot find the window manager: Gtk-WARNING **: cannot open display:
  3. It's not very edit-friendly, I wish there were some kind of rule where I can just type the LABEL for certain partitions on which I would like to trigger certain scripts.

I would like to see a general improvement for the UDEV rule, because apart from the many questions and answers about it, here and elsewhere, they all seem a bit different from each other and most of them trigger multiple times.

But most importantly, how, in any way, can I make the connection from here to a script in my home that has access to stuff like my session and my screen so that zenity can work?

Redsandro

Posted 2013-04-14T16:52:34.720

Reputation: 496

Answers

0

You already found the answer. The script (zenity) needs an X Window Server for displaying a message. The script is run from udev and has no display attached to it. You can solve this by hardwiring the DISPLAY variable in your script, i.e.

DISPLAY=:0; export DISPLAY

The drawback to this is, it works only, if you are the only user and/or know the display in advance. If there are multiple users on your system, the display might be anything else, for example :1, :2, and so on. Or another users gets the zenity message on his screen.

A better approach would be to split the detection of the event and the interaction with the user or display of the message.

For this you can create a script or program, which runs in your GUI session and listens for a trigger from a daemon or the udev trigger script.

A third possibility could be to connect to the udisks-daemon and ask for information, when the external device is plugged in. You can try udisks --monitor or udisks --monitor-detail for this and parse the output, whenever an event happens.

There seems to be a udisksctl command, which does the same with a slightly different syntax. Maybe it's just a newer version of the udisks command.

You can also look at some Gui tools like GNOME Disks, which rely on the udev/udisks system as well.

Update:

The multiple invocations usually arise from the report of the various subsystems. You can see that, when you log the environment to some log file in the /usr/local/bin/test.sh script

umask 077
mkdir -p /tmp/udevtest.d
env >>/tmp/udevtest.d/udevtest.log

When I plugin a USB stick, I get the following reports

$ grep -e ACTION -e SUBSYSTEM /tmp/udevtest.d/udevtest.log
ACTION=add
SUBSYSTEM=usb
ACTION=add
SUBSYSTEM=usb
ACTION=add
SUBSYSTEM=scsi
ACTION=add
SUBSYSTEM=scsi_host
ACTION=add
SUBSYSTEM=scsi
ACTION=add
SUBSYSTEM=scsi
ACTION=add
SUBSYSTEM=scsi_disk
ACTION=add
SUBSYSTEM=scsi_generic
ACTION=add
SUBSYSTEM=scsi_device
ACTION=add
SUBSYSTEM=bsg
ACTION=add
SUBSYSTEM=block
ACTION=add
SUBSYSTEM=block

You can also add DEVTYPE to distinguish between the two usb or disk reports. So, in order to reduce the reports to just a few or even only one call, you must be more specific and add additional conditions to your udev rules file, for example choose the SUBSYSTEM=scsi_disk or whatever is appropriate for your device.

Olaf Dietsche

Posted 2013-04-14T16:52:34.720

Reputation: 421

Thank you for the response and mentioning alternatives. You were right, DISPLAY=:0 did the trick. This answer addressess subquestion 2, but as subquestion 1 predicted, I now get my zenity popup about 30 times for 1 plugged in drive. Any idea how I can tone this down? Preferably I would like the script to be called with just the partition name as argument. (E.g. script is called 3 times with 3 partitions.)

I also tried udisks because it seems so easy, but it just sits there claiming to be monitoring, but not reporting anything I plug in. Maybe it's not implemented correctly for Ubuntu. – Redsandro – 2013-04-22T13:24:14.300

Ah udiskctl does monitor events. I will look into it further if I can't figure out how to do it in the udev rules as initially planned. – Redsandro – 2013-04-22T13:33:13.640

@Redsandro Please see updated answer. – Olaf Dietsche – 2013-04-22T16:03:12.653

Thank you. It's still a puzzle, but I'm better informed now. I have accepted your answer. – Redsandro – 2013-04-23T12:03:38.297

0

For anybody else reading this, the only way I was able to get my script in Kali Linux 2016 to work, was like this:

#!/bin/bash
set -x
xhost local:root
export DISPLAY=:0.0
su root -c 'zenity --notification --text="I am a notification!"'

sMyles

Posted 2013-04-14T16:52:34.720

Reputation: 101