如何以另一种方式关闭ubuntu机器?

我有一个要求,当用户注销或关闭谷歌浏览器时,需要关闭ubuntu机器,谁能给我一个更好的主意和一些如何做到这一点的细节?

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

谢谢。

内容:

  1. 一般想法
  2. 脚本来源
  3. 其他建议

1.一般想法:

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

在此处输入图像描述

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

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

2.脚本来源

它也可以在GitHub上获得

/usr/bin/inhibit_logout.py

 #!/usr/bin/env python3 # -*- coding: utf-8 -*- # Author: Serg Kolo,<1047481448@qq.com> # 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快捷键以进行注销。 考虑删除那个