我有一个要求,需要在用户注销或关闭 Google Chrome 时关闭 ubuntu 机器,有人能给我一个更好的想法和一些关于如何做到这一点的细节吗?
我想我应该编写一个 shell 脚本来监视某些进程并将该脚本作为 cron 作业运行。
谢谢。
答案1
内容:
- 总体思路
- 脚本源
- 其他建议
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 快捷键。考虑也删除该快捷键