如何在(仅在之前)注销Unity会话时运行本地命令(运行脚本)?
冒着发布重复问题的风险:
当我退出时,如何运行本地脚本(作为当前用户)?
我读过(并尝试过)其他人:
- 这个 (Marton的版本),完全没有做任何事情,用于创建文件的简单脚本,脚本的绝对路径(可执行)和文件。
- 这一个 ,必须过时; 它让我从命令行中删除文件,以便能够再次使用我的系统。
- 我也看了这个 ,没有成功。
我相信我一定是在做错事,但是找不到我的盲点。
上下文
寻找这个问题的优雅解决方案(解决方法),可能是一个错误的结果,我制作了一个脚本,根据参数,可以获取当前桌面图标排列的快照 ,或根据最后一个排列图标快照。 该脚本工作正常,但实际上不能作为后台脚本运行。
因此,脚本应该在注销时运行以获得安排,显然由当前用户运行。
基础理论
您可能知道也可能不知道,使用dbus实现了很多Unity操作。 dbus的一大优点是,您可以通过在命令行中调用适当的方法来执行许多根需要的操作,而无需使用管理员帐户,例如关闭系统 。
特别是在我们的案例中,我们对com.canonical.Unity
服务, /com/canonical/Unity/Session
路径感兴趣。 您可以使用qdbus
命令列出有关它的信息。 特别是我们对其中有Requested
信号感兴趣。
$ qdbus com.canonical.Unity /com/canonical/Unity/Session | grep 'signal.*Requested.*' signal void com.canonical.Unity.Session.LockRequested() signal void com.canonical.Unity.Session.LogoutRequested(bool have_inhibitors) signal void com.canonical.Unity.Session.RebootRequested(bool have_inhibitors) signal void com.canonical.Unity.Session.ShutdownRequested(bool have_inhibitors) signal void com.canonical.Unity.Session.UnlockRequested()
当用户在Unity顶部栏右侧的下拉会话菜单中单击任何关闭,锁定,注销或重新启动项时,这些信号将显示在总线上。 所以我们需要做的是:
- 监控总线以显示这些信号。
- 一旦它们出现 – 执行某个动作。
当然, 最大的免责声明是,如果用户使用sudo shutdown -P now
或gnome-session-quit
,那将不会告诉dbus
,所以不需要采取任何行动。
监控dbus
方便地有一个命令, dbus-monitor
,我们可以使用一组选项过滤其输出,并使用while read do … done
结构对其执行操作
Bellow是一个简单监控脚本的示例。
dbus-monitor --profile "interface='com.canonical.Unity.Session',type=signal" | \ while read -r line; do echo "$line" sleep 0.25 done
它的作用仅仅是监视总线上的信号,如果出现则将它们回显到stdout; 当然,回声可以是任何命令。 运行它,并尝试单击会话菜单中应生成信号的每个项目,您应该看到如下内容:
$ ./logout_monitor.sh sig 1458319246 172587 2 /org/freedesktop/DBus org.freedesktop.DBus NameAcquired sig 1458319251 213766 5496 /com/canonical/Unity/Session com.canonical.Unity.Session RebootRequested sig 1458319265 62555 5525 /com/canonical/Unity/Session com.canonical.Unity.Session LogoutRequested sig 1458319271 856770 5555 /com/canonical/Unity/Session com.canonical.Unity.Session LockRequested sig 1458319273 223940 5564 /com/canonical/Unity/Session com.canonical.Unity.Session Locked sig 1458319276 991413 5604 /com/canonical/Unity/Session com.canonical.Unity.Session UnlockRequested sig 1458319278 3443 5606 /com/canonical/Unity/Session com.canonical.Unity.Session Unlocked
所以现在我们有一个监控function,可以在中断发生后执行操作。 现在,为了解决您尝试解决的具体问题,您的脚本正在拍摄桌面上图标的快照。 如果我们每次发出信号时拍摄快照都没有坏处 – 它不必专门重启或关机。 因此,如果我们监视特定的Unity接口以获取信号并在每个信号到达时拍摄快照,我们就可以简化脚本编写。
中断驱动的脚本
Bellow你可以看到一个中断驱动的脚本,它将监视总线上的信号(忽略第一个),如果我们有信号进入,那么调用一个中断函数(在你的情况下将是你的图标快照脚本)写的)。
#!/bin/bash main() { ARG="cow" dbus-monitor --profile "interface='com.canonical.Unity.Session',type=signal" | while read -r line; do grep -q '.*NameAcquired.*' <<< "$line" && continue # Ignore that first line if [ -n "$line" ];then interrupt $ARG # call your python snapshot script here fi done } interrupt() { echo 'Old McDonald had a ' $ARG ' eieio ' } main
注意 :Dbus依赖于GUI会话,因为(据我所知)它从Unity / Gnome登录开始。 较旧的环境,如blackbox和openbox,以及TTY环境都无法启动dbus会话,因此如果您尝试在~/.profile
启动它,该脚本会发呕(我有一个用户试图做类似的事情而且他得到了陷入麻烦)。 使用Unity或Gnome的启动应用程序启动此类脚本 。
超越这个脚本
- Dbus有很多API,包括python
- 我更喜欢使用
qdbus
因为它很简单,但总是可以使用dbus-send
。 例子 - 中断function可以是任何东西,甚至是其他
dbus
方法。 有很多值得关注的问题。
琐事 : 如果apt正在运行,我已经使用了同样的方法来防止关机