面临发布重复问题的风险:
我如何在注销时运行本地脚本(以当前用户身份)?
我读过(并尝试过)以下内容:
- 这个(Marton 的版本)什么都没做,只是用一个简单的脚本创建一个文件、脚本(可执行)和文件的绝对路径。
- 这个,它肯定已经过时了;它让我从命令行删除该文件才能再次使用我的系统。
- 我也调查过这个,没有成功。
我相信我在这里一定是做错了什么,但却找不到我的盲点是什么。
语境
寻找一个优雅的解决方案(解决方法)这个问题,可能是由于错误,我编写了一个脚本,根据参数,拍摄快照当前桌面图标排列,或排列图标,根据最后一张快照。该脚本运行良好,但实际上不适合作为后台脚本运行。
因此脚本应该在注销时运行得到该安排显然是由当前用户运行的。
答案1
基本理论
你可能知道也可能不知道,很多 Unity 动作都是使用总线. dbus 最大的便利在于,您可以通过在命令行中调用适当的方法执行许多需要 root 权限的操作,而无需拥有管理员帐户,例如关闭系统。
具体来说,在我们的例子中,我们感兴趣的是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
结构对其执行操作
下面是一个简单的监控脚本的示例。
dbus-monitor --profile "interface='com.canonical.Unity.Session',type=signal" | \
while read -r line;
do
echo "$line"
sleep 0.25
done
它所做的只是监视总线上的信号,如果出现信号,则将其回显到标准输出;当然,echo 可以是任何命令。运行它,并尝试单击会话菜单中应生成信号的每个项目,您应该会看到类似以下内容:
$ ./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
因此,现在我们有一个监控函数,可以在发生中断时执行操作。现在,为了解决您试图解决的具体问题,您的脚本正在对桌面上的图标进行快照。如果我们每次发生信号时都进行快照,则不会造成任何损害 - 不必专门重新启动或关闭。因此,如果我们监视该特定 Unity 接口的信号并在每个信号到达时进行快照,我们可以简化脚本。
中断驱动脚本
下面您可以看到一个中断驱动的脚本,它将监视总线上的信号(忽略第一个信号),如果有信号进来,则调用中断函数(在您的情况下,它将是您编写的图标快照脚本)。
#!/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 ' e-i-e-i-o '
}
main
笔记:Dbus 依赖于 GUI 会话,因为(据我所知)它以 Unity/Gnome 登录开始。较旧的环境(例如 blackbox 和 openbox)以及 TTY 环境不要启动 dbus 会话,因此如果您尝试启动它,该脚本将会失败~/.profile
(我有一个用户尝试做这样的事情,结果遇到了麻烦)。使用 Unity 或 Gnome 的启动应用程序启动此类脚本程序。
超越这个脚本
琐事:我用过同样的方法如果 apt 正在运行,则防止关机