我正在尝试编写一个Python恶魔,它会对会话结束做出反应(即TTY已关闭,因为已退出bash等)。根据我的理解,SIGHUP应该在某个时刻被发送到过程中(我对具体细节模糊不清),但到目前为止我还没有能够捕捉到任何东西。
这是我的非功能性python尝试:
#!/usr/bin/env python
import os
import sys
import signal
import time
def log_to_disk(signum, frame):
with open("/tmp/SIGNAL", "w") as f:
f.write("Received %d!\n" % signum)
def fork():
try:
pid = os.fork()
if pid > 0:
# Exit parent
print "Parent exiting. Bye!"
sys.exit(0)
except OSError as e:
print "Error while forking! (%s)" % str(e)
sys.exit(1)
fork()
os.chdir('/')
os.setsid()
os.umask(0)
fork() # Second fork.
# Catch ALL the signals just in case.
for i in [x for x in dir(signal) if x.startswith("SIG")]:
try:
signum = getattr(signal, i)
signal.signal(signum, log_to_disk)
except Exception as e:
print "Couldn't handle %s (%s)." % (i, str(e))
while True:
time.sleep(10)
我正在做什么:我在服务器上SSH,在那里启动脚本,然后关闭我的SSH会话。然后我重新登录,希望/tmp/SIGNAL
文件已经创建,但到目前为止还没有运气。如果我使用kill
向进程发送信号,则会显示该文件,因此我假设这不是处理程序的问题。
我也尝试过只翻一次和/或评论chdir/setsid/umask
部分,但我还没有收到任何东西。
我探索过的另一条途径是只分叉一次,并试图定期写信给TTY,希望在它关闭的某个时刻收到SIGTTOU。
任何人都可以帮助我吗?
答案 0 :(得分:0)
我已经找到了一种解决方法,即检测何时stdout
无法解析为TTY名称:
import os
import sys
import time
def fork():
try:
pid = os.fork()
if pid > 0:
# Exit parent
print "Parent exiting. Bye!"
sys.exit(0)
except OSError as e:
print "Error while forking! (%s)" % e.message
sys.exit(1)
fork()
os.chdir('/')
os.setsid()
os.umask(0)
fork() # Second fork.
while True:
time.sleep(1)
with open("/tmp/SIGNAL", "a+") as f:
try:
os.ttyname(1) # 1 = stdout
except:
f.write("The session has been shut down :)\n")
sys.exit(0)
我仍然不确定到底发生了什么:当我查看ps
中的Python进程时,TTY列显示了一个问号(?),所以我看不出它是怎么回事能够在双叉后解析它的标准输出。
如果有人想出一个没有TTY的shell的答案,我也会把这个问题保持开放一段时间!