会话在Python

时间:2017-01-11 01:54:40

标签: python linux signals

我正在尝试编写一个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。

任何人都可以帮助我吗?

1 个答案:

答案 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的答案,我也会把这个问题保持开放一段时间!