在@ensc所说的基础上,您可以改为监听自己的D-Bus(系统会话)信号。该org.freedesktop.login1.Manager
界面的一般工作流程为:
- 禁止系统睡眠(也许也关闭)
Inhibit(what, who, why, mode)
what
:sleep
或shutdown:sleep
who
:unmount_cifs
或任何您称呼的脚本
why
:unmounting cifs X before suspend ...
或等效
mode
:delay
抑制最大。5s(默认)或block
无限期阻塞(我建议使用第一个。如果脚本停滞,笔记本将永远不会进入睡眠状态。)
- 这将返回一个“持有”锁的文件描述符
- 现在您收听信号
PrepareForSleep
,它将True
在即将暂停或休眠以及False
恢复和解冻时返回)
PrepareForShutdown
,它将True
在即将关闭时返回,并应在重新False
开机时返回(相反,它还会False
在返回的同时返回True
,这对我来说是没有意义的,因此在False
这里我将忽略该部分;您可能已经有了某种自动安装脚本无论如何在系统启动时,对吗?
- 处理完
True
信号(即卸载)后,立即通过关闭文件描述符(由返回)释放锁定Inhibit(...)
,以便机器可以尽可能快地进入睡眠或关闭状态,而无需等待整个5s(甚至在block
模式下无限期)
- 您可以
False
通过重新安装(也许首先等待网络恢复)来处理信号(恢复/解冻),然后创建一个新的锁Inhibit(...)
(用于下次睡眠或关闭)
在Python(2.7)中,它可能类似于:
#!/usr/bin/env python
import os, atexit, dbus, gobject
from dbus.mainloop import glib
def login1ManagerDBusIface():
system_bus = dbus.SystemBus()
proxy = system_bus.get_object( 'org.freedesktop.login1',
'/org/freedesktop/login1' )
login1 = dbus.Interface( proxy, 'org.freedesktop.login1.Manager')
return login1
def sleepShutdownInhibit():
login1 = login1ManagerDBusIface()
fd = login1.Inhibit( 'shutdown:sleep', 'unmount_cifs',
'Unmounting before suspend/shutdown ...',
'delay' )
return fd
def take_lock():
global FD
FD = sleepShutdownInhibit()
def remove_lock():
global FD
if FD:
os.close( FD.take() )
FD = None
def signal_handler(boolean, member=None):
if boolean: ## going to suspend/hibernate or shutdown
## PLACE YOUR UNMOUNT STUFF HERE
remove_lock()
else: ## resume/thaw
if member == 'PrepareForSleep':
## PLACE YOUR MOUNT STUFF HERE
take_lock()
if __name__ == '__main__':
take_lock()
atexit.register(remove_lock)
login1 = login1ManagerDBusIface()
for signal in ['PrepareForSleep', 'PrepareForShutdown']:
login1.connect_to_signal(signal, signal_handler,
member_keyword='member')
glib.DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()
loop.run()
在本要点中,您将找到我的Pidgin包装,使用完全相同的方法在睡眠和关机时断开IM帐户的连接。
另请参见关于Inhibitor Locks和logind
D-Bus API的官方freedesktop文档。