如何在登录 ubuntu 之前在 python 守护进程中使用 DBUS
How to use DBUS in python daemon before login in ubuntu
(背景:我最近看到一个很棒的 Android 应用程序与 linux 配对,允许用户解锁和锁定锁屏。但是该项目不再工作和维护了。我我正在努力让它工作,但 DBUS 有问题)
创建了一个守护进程服务,它打开一个套接字并等待传入的连接。当它接收到连接时,它会尝试获取 DBUS_ADDRESS 和 UID 并将其设置在环境变量中:
os.environ['DBUS_SESSION_BUS_ADDRESS'] = DBUS_ADDRESS
os.seteuid(UID)
这就是我获取 DBUS 和 UID 地址的方式:
def get_bus_and_uid():
'''Find the first running process with a DBUS session address run by
a non-daemon user, and return both the DBUS_SESSION_BUS_ADDRESS and the
uid.'''
DBUS_ADDRESS = 'DBUS_SESSION_BUS_ADDRESS'
UIDS = 'uids'
# Find all non-daemon users.
all_users = [i.split(':') for i in open('/etc/shadow').readlines()]
users = [i[0] for i in all_users if i[1] not in ('!', '*')]
# Find the first non-daemon user process with a DBUS_SESSION_BUS_ADDRESS
# in it's environment.
user_address = {}
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=['pid', 'username', UIDS])
except psutil.NoSuchProcess:
pass
user = pinfo['username']
# Ignore process run by daemons.
if user not in users:
continue
environ = psutil.Process(pid=pinfo['pid']).environ()
if DBUS_ADDRESS in environ:
# pinfo[uids] returns real, effective and saved uids.
return environ[DBUS_ADDRESS], pinfo[UIDS][0]
return None, None
但是问题是如果在至少一个用户登录后调用 get_bus_and_uid() 则此方法有效。如果在首次登录之前建立任何连接,则会失败。
我尝试了什么:
我试图通过守护进程使用 $dbus-launch 启动 DBUS 服务,但仍然没有成功。
有没有其他方法可以使用 DBUS 与 org.(gnome|freedesktop).screensaver 通信?
(这一切都是为了与 org.(gnome|freedesktop).screensaver 进行通信)
github 中的项目:Remote-linux-unlocker/unlocker-daemon.py
感谢任何帮助,提前致谢。
编辑:如果没有活动的桌面会话,则也没有可解锁的内容。感谢您的澄清@tripleee
如果session与systemd-logind集成(GNOME、Cinnamon、KDE都支持),
loginctl unlock-sessions
将解锁所有会话。
(背景:我最近看到一个很棒的 Android 应用程序与 linux 配对,允许用户解锁和锁定锁屏。但是该项目不再工作和维护了。我我正在努力让它工作,但 DBUS 有问题)
创建了一个守护进程服务,它打开一个套接字并等待传入的连接。当它接收到连接时,它会尝试获取 DBUS_ADDRESS 和 UID 并将其设置在环境变量中:
os.environ['DBUS_SESSION_BUS_ADDRESS'] = DBUS_ADDRESS
os.seteuid(UID)
这就是我获取 DBUS 和 UID 地址的方式:
def get_bus_and_uid():
'''Find the first running process with a DBUS session address run by
a non-daemon user, and return both the DBUS_SESSION_BUS_ADDRESS and the
uid.'''
DBUS_ADDRESS = 'DBUS_SESSION_BUS_ADDRESS'
UIDS = 'uids'
# Find all non-daemon users.
all_users = [i.split(':') for i in open('/etc/shadow').readlines()]
users = [i[0] for i in all_users if i[1] not in ('!', '*')]
# Find the first non-daemon user process with a DBUS_SESSION_BUS_ADDRESS
# in it's environment.
user_address = {}
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=['pid', 'username', UIDS])
except psutil.NoSuchProcess:
pass
user = pinfo['username']
# Ignore process run by daemons.
if user not in users:
continue
environ = psutil.Process(pid=pinfo['pid']).environ()
if DBUS_ADDRESS in environ:
# pinfo[uids] returns real, effective and saved uids.
return environ[DBUS_ADDRESS], pinfo[UIDS][0]
return None, None
但是问题是如果在至少一个用户登录后调用 get_bus_and_uid() 则此方法有效。如果在首次登录之前建立任何连接,则会失败。
我尝试了什么: 我试图通过守护进程使用 $dbus-launch 启动 DBUS 服务,但仍然没有成功。 有没有其他方法可以使用 DBUS 与 org.(gnome|freedesktop).screensaver 通信?
(这一切都是为了与 org.(gnome|freedesktop).screensaver 进行通信)
github 中的项目:Remote-linux-unlocker/unlocker-daemon.py
感谢任何帮助,提前致谢。
编辑:如果没有活动的桌面会话,则也没有可解锁的内容。感谢您的澄清@tripleee
如果session与systemd-logind集成(GNOME、Cinnamon、KDE都支持),
loginctl unlock-sessions
将解锁所有会话。