内容:

内容:

我有一个要求,需要在用户注销或关闭 Google Chrome 时关闭 ubuntu 机器,有人能给我一个更好的想法和一些关于如何做到这一点的细节吗?

我想我应该编写一个 shell 脚本来监视某些进程并将该脚本作为 cron 作业运行。

谢谢。

答案1

内容:

  1. 总体思路
  2. 脚本源
  3. 其他建议

1.总体思路:

可以通过dbus进程间通信总线禁止从 Unity 或 Gnome 会话注销,该总线允许代表普通用户以 root 身份执行某些操作。在我的测试中,注销似乎在 Unity 中是强制的;这意味着禁止只会持续几秒钟,但足以让我们运行关机命令。一旦用户在注销对话框中单击“注销”选项,禁止锁也会被打破

在此处输入图片描述

下面的脚本正是这样做的。它同时运行两个函数。一个函数等待 Chrome 出现,然后等待 Chrome 进程消失并关闭。另一个函数禁止注销,直到锁定被打破,一旦锁定被打破,它就会调用关闭函数。

此脚本旨在作为启动应用程序添加。由于您必须为公司中的每个用户使用它,因此我建议您将此.desktop代码的文件放入/etc/xdg/autostart文件夹中。这样它将自动为所有用户运行

2.脚本来源

也可以在GitHub 作为要点

/usr/bin/inhibit_logout.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#    Author: Serg Kolo,<[email protected]>
#    Date: September 28, 2016
#    Purpose: Monitoring script that shutsdown
#             system if logout occurs or chrome exits
#    Written for: http://askubuntu.com/q/828524/295286

from gi.repository import Gdk
import dbus
import os
import threading
import subprocess

def get_dbus(bus_type,obj,path,interface,method,*argv):

    if bus_type == "session":
        bus = dbus.SessionBus() 
    if bus_type == "system":
        bus = dbus.SystemBus()
    proxy = bus.get_object(obj,path)
    method = proxy.get_dbus_method(method,interface)
    if argv:
        return method(*argv)
    else:
        return method()  

def shutdown():
    ''' Wrapper for dbus Shutdown method '''
    get_dbus('session',
             'com.canonical.Unity', 
             '/com/canonical/Unity/Session', 
             'com.canonical.Unity.Session',
             'Shutdown',None)

def is_inhibited():
    ''' wrapper for IsInhibited dbus method'''
    return get_dbus('session',
             'org.gnome.SessionManager', 
             '/org/gnome/SessionManager', 
             'org.gnome.SessionManager',
             'IsInhibited',
             1)

def is_chrome_running():
    '''checks output of pgrep for
       any chrome processes'''
    try:
         null=open(os.devnull,'w')
         subprocess.check_call(['pgrep','-f','chrome'],stdout=null,stderr=null)    
    except subprocess.CalledProcessError:
        return False
    else:
        return True

def inhibit_logout():
    ''' Inhibits log out temporarily so that we have
    enough time to shutdown '''

    # pretend we are root window
    # and inhibit logout on our behalf
    root_window_xid = int(Gdk.Screen.get_default().get_root_window().get_xid())
    get_dbus('session',
             'org.gnome.SessionManager',
             '/org/gnome/SessionManager',
             'org.gnome.SessionManager',
             'Inhibit', 
             'root_window',
             root_window_xid, 
             'TEST REASON', 
             1)

    # once the inhibitor is removed, shutdown
    while is_inhibited():
       pass
    shutdown()    

def capture_chrome():
    # wait for chrome to start
    while not is_chrome_running():
       pass

    # start waiting till it exits
    while is_chrome_running():
       pass

    # once chrome exits, shutdown
    shutdown()

def main():
    ''' program entry point'''
    threading.Thread(target=inhibit_logout).start()     
    threading.Thread(target=capture_chrome).start()

if __name__ == '__main__':
    main()

/etc/xdg/autostart/inhibit_logout.desktop

[Desktop Entry]
Type=Application
Name=Logout Inhibitor
Exec=/usr/bin/inhibit_logout.py
OnlyShowIn=GNOME;Unity;
Terminal=false

3.补充建议:

为了防止用户明确注销并打破抑制锁,请使用

gsettings set com.canonical.indicator.session suppress-logout-menuitem true

这将删除注销选项,但不会删除用于注销的 Ctrl+Alt+Del 快捷键。考虑也删除该快捷键

相关内容