I am trying to launch a dbus client, programmed via a Python script, from another script launched via a udev rule (which is run as root), and I need this dbus client to be left running when the script finishes.
The dbus client to launch is:
#!/usr/bin/python3
from gi.repository import Gtk
from gi.repository import Notify
import dbus
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
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')
Gtk.main()
I need to get the script to launch a dbus client for each existing user on the system, continue its execution to completion, and exit; without killing the clients you just launched.
I'm trying it this way, using nohup
:
#Get online users list
user_list=$(who | cut -d " " -f 1)
#Set display
export DISPLAY=":0"
#For each user, launch dbus client
for user in $user_list
do
nohup su $user -c '/usr/bin/pendrive-reminder/client.py' &
done
But, when launching it like this, the dbus client leaves the script blocked, which, once its sequence of instructions has finished, remains running in the "defunct" state (as a zombie process).
And by doing this, it also crashes udev, which stops responding to the following system events
how could i solve it?
UPDATE
I have changed the library I use for the main loop of the dbus client, removing Gtk and using GLib
The code looks like this:
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()
Now, after this, I have noticed some changes:
If I launch the dbus client manually from the terminal, it ends when I do ctrl+c (the previous one stayed running and I had to end it with the command
kill
)If I launch it from the script, with
nohup su $user -c '/usr/bin/pendrive-reminder/client.py' & disown
the script finishes its instructions, and ends a few minutes later (previously it never finished).
Now what I need is for the script, instead of ending after a few minutes, to end immediately
In addition to nohup, you have to add
& disown
to the end of the process to disconnect it from the list of active processes of the shell that launches it.Example:
After doing several tests, I have managed to get the script to launch the dbus client and finish, leaving the dbus client running.
Launching the script from terminal I see that the script ends instantly, and the dbus client stays running.
The script code is this:
The client code looks like this: