在Linux下检测Python / GTK中的用户注销/关闭 – 未收到SIGTERM
好吧这可能是一个很难的,我有一个pyGTK应用程序,由于我无法捕获/控制的X Window错误导致随机崩溃.
所以我创建了一个包装器,一旦检测到崩溃就重新启动应用程序,现在出现了问题,当用户注销或关闭系统时,应用程序以状态1退出.但是在某些X错误上它也会这样做. 所以我尝试了任何事情以捕获关闭/注销,但没有成功,这是我尝试过的: import pygtk import gtk import sys class Test(gtk.Window): def delete_event(self,widget,event,data=None): open("delete_event","wb") def destroy_event(self,data=None): open("destroy_event","wb") def destroy_event2(self,data=None): open("destroy_event2","wb") def __init__(self): gtk.Window.__init__(self,gtk.WINDOW_TOPLEVEL) self.show() self.connect("delete_event",self.delete_event) self.connect("destroy",self.destroy_event) self.connect("destroy-event",self.destroy_event2) def foo(): open("add_event","wb") def ex(): open("sys_event","wb") from signal import * def clean(sig): f = open("sig_event","wb") f.write(str(sig)) f.close() exit(0) for sig in (SIGABRT,SIGILL,SIGINT,SIGSEGV,SIGTERM): signal(sig,lambda *args: clean(sig)) def at(): open("at_event","wb") import atexit atexit.register(at) f = Test() sys.exitfunc = ex gtk.quit_add(gtk.main_level(),foo) gtk.main() open("exit_event","wb") 其中没有一个成功,是否有任何低级方法来检测系统关闭?谷歌没有找到与此相关的任何内容. 我想一定有办法,对吗? :/ 编辑: 我已经创建了这个shell脚本: #!/bin/bash trap test_term TERM trap test_hup HUP test_term(){ echo "teeeeeeeeeerm" >~/Desktop/term.info exit 0 } test_hup(){ echo "huuuuuuuuuuup" >~/Desktop/hup.info exit 1 } while [ true ] do echo "idle..." sleep 2 done 并且还创建了一个.desktop文件来运行它: [Desktop Entry] Name=Kittens GenericName=Kittens Comment=Kitten Script Exec=kittens StartupNotify=true Terminal=false Encoding=UTF-8 Type=Application Categories=Network;GTK; Name[de_DE]=Kittens 通常这应该在注销时创建术语文件,并在使用&启动时创建hup文件.但不是我的系统. GDM根本不关心脚本,当我重新编写时,它仍在运行. 我也试过使用shopt -s huponexit,但没有成功. EDIT2: Wrapper Script,that catches errors and restarts the programm -> Main Programm with GTK Mainloop -> Background Updater Thread 流程是这样的: Start Wrapper -> enter restart loop while restarts < max: -> start program -> check return code -> write error to file or exit the wrapper on 0 现在关机时,启动程序返回1.这意味着要么是hanup还是父进程终止,主要问题是找出这两个中的哪一个刚刚发生. 如果你想看看实际的代码,请在GitHub上查看: 解决方法
好的,我终于找到了解决方案:)
在这种情况下,你根本不能依赖信号.您必须连接到桌面会话才能收到注销即将发生的通知. import gnome.ui gnome.program_init('Program',self.version) # This is going to trigger a warning that program name has been set twice,you can ignore this,it seems to be a problem with a recent version of glib,the warning is all over the place out there client = gnome.ui.master_client() # connect us to gnome session manager,we need to init the program before this client.connect('save-yourself',self.on_logout) # This gets called when the user confirms the logout/shutdown client.connect('shutdown-cancelled',self.on_logout_cancel) # This gets called when the logout/shutdown is canceled client.connect('die',self.on_logout) # Don't know when this gets called it never got in my tests def on_logout(self,*args): # save settings an create a file that tells the wrapper that we have exited correctly! # we'll still return with status code 1,but that's just gtk crashing somehow def on_logout_cancel(self,*args): # simply delete the logout file if it exists 这里有一个重要的注意事项:不要尝试在on_logout中退出程序,如果这样做,GNOME将无法识别您的程序已退出,并将为您提供某些程序仍在运行的对话框. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |