AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 720380
Accepted
Jacob Vlijm
Jacob Vlijm
Asked: 2016-01-13 13:53:17 +0800 CST2016-01-13 13:53:17 +0800 CST 2016-01-13 13:53:17 +0800 CST

如何在(就在之前)注销 Unity 会话时运行本地命令(运行脚本)?

  • 772

冒着发布重复问题的风险:

注销时如何运行本地脚本(作为当前用户)?

我阅读(并尝试过)除其他外:

  1. 这个(Marton 的版本)完全没有做任何事情,用于创建文件的简单脚本、脚本的绝对路径(可执行)和文件。
  2. 这个,一定是过时的;它使我从命令行中删除了该文件,以便能够再次使用我的系统。
  3. 我也调查了这个,没有成功。

我相信我在这里一定做错了什么,但无法找出我的盲点。

语境

为这个问题寻找一个优雅的解决方案(解决方法),大概是一个错误的结果,我制作了一个脚本,根据参数,根据最后一个快照。该脚本运行良好,但实际上不适合作为后台脚本运行。

因此,脚本应该在注销时运行以获取安排,显然由当前用户运行。

14.04
  • 1 1 个回答
  • 1288 Views

1 个回答

  • Voted
  1. Best Answer
    Sergiy Kolodyazhnyy
    2016-03-19T09:12:15+08:002016-03-19T09:12:15+08:00

    基础理论

    您可能知道也可能不知道,很多 Unity 操作都是使用dbus实现的。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 nowor 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
    

    它所做的只是监视总线上的信号,并在它们出现时将它们回显到标准输出;当然 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 的启动应用程序启动此类脚本。

    超越这个脚本

    • Dbus 有很多 API,包括python
    • 我更喜欢使用qdbus,因为它很简单,但总是可以使用dbus-send. 例子
    • 中断函数可以是任何东西,甚至是其他dbus方法。有很多东西要研究。

    琐事:如果 apt 正在运行,我使用相同的方法来防止关机

    • 3

相关问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve