I'm trying to use a udev rule to launch a dbus client from a script.
The udev rule will jump when a pendrive is connected, and execute the script usbdevinserted.sh
, which will copy the identifier of the pendrive to a file and launch the dbus client
The udev rule is this:
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", RUN+="/usr/bin/pendrive-reminder/usbdevinserted.sh"
The code of usbdevinserted.sh
this:
set 2>&1 | grep DEVPATH | cut -d "=" -f 2 >> /tmp/usbdevinfo
#Get list of users with graphic session started, and their active display
userdisplay=$(who | gawk '/\(:[[:digit:]](\.[[:digit:]])?\)/ { print $1 ";" substr($NF, 2, length($NF)-2) }' | uniq)
#for each user, show notification and (only in polkit >= 106) launch dbus client
for element in $userdisplay
do
#get username
user=$(echo $element | cut -d ";" -f 1)
#get display active of this user
export DISPLAY=$(echo $element | cut -d ";" -f 2)
#Send notification to user
su $user -c 'notify-send "Pendrive Reminder" "Shutdown lock enabled. The shutdown will be unlocked when pendrive is disconnected"'
#if polkit version >=106, also launch dbus client
if test $polkit_version -ge 106
then
su $user -c 'python /usr/bin/pendrive-reminder/client.py' &
fi
done
And the dbus client ( client.py
) is this:
#!/usr/bin/python3
from gi.repository import GLib
from gi.repository import Notify
import dbus
from dbus.mainloop.glib import DBusGMainLoop
dbus_loop = DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus(mainloop=dbus_loop)
loop = GLib.MainLoop()
def msg_handler(*args,**keywords):
try:
#show notification to desktop
Notify.init('Pendrive Reminder')
notify = Notify.Notification.new('Pendrive Reminder', 'Shutdown lock enabled. Disconnect pendrive to enable shutdown')
notify.show()
except:
pass
bus.add_signal_receiver(handler_function=msg_handler, dbus_interface='org.preminder', path_keyword='path')
loop.run()
The idea is that the script ( usbdevinserted.sh
) ends, leaving the dbus client running.
I have tried launching it manually from the terminal, and it works fine: the script ends and leaves the dbus client running.
But, when I launch the script from the udev rule, the script, even after executing its sequence of instructions, stays zombie and does not die until after a few minutes, time in which it leaves udev blocked.
And, if I launch the script from udev, removing the part where the dbus client is launched ( client.py
), the script ends correctly without being zombie.
Do you know where the problem may be?
UPDATE
As I have indicated in the comments, I have tried with:
su $user -c '/usr/bin/pendrive-reminder/client.py &>/dev/null' & | at now
But now the dbus client does not get launched (or dies next to the script) I've also tried with:
su $user -c '/usr/bin/pendrive-reminder/client.py &>/dev/null' & - batch
But the script does not end (not even as a zombie)
And with:
su $user -c '/usr/bin/pendrive-reminder/client.py &>/dev/null' & - at
the script becomes zombie again until a few minutes later