如何在Windows上退出信号功能?

时间:2017-06-08 15:45:53

标签: python windows python-2.7 signals

我在Windows上使用Python 2.7编写了以下代码。我想检查当前python脚本的更新并更新它,如果有更新,通过ftp服务器保留文件名的新版本,然后在终止通过os.kill的当前执行新的python脚本SIGNTERM

我使用exit函数方法,但我在Windows中读到这只适用于atexit库和默认的python exit方法。所以我使用了atexit.register()和信号处理程序的组合。

***necessary libraries***

filematch = 'test.py'
version = '0.0'
checkdir = os.path.abspath(".")
dircontent = os.listdir(checkdir)
r = StringIO()

def exithandler():
    try:
        try:
            if filematch in dircontent:
                os.remove(checkdir + '\\' + filematch)
        except Exception as e:
            print e

        ftp = FTP(ip address)
        ftp.login(username, password)
        ftp.cwd('/Test')

        for filename in ftp.nlst(filematch):
            fhandle = open(filename, 'wb')
            ftp.retrbinary('RETR ' + filename, fhandle.write)
            fhandle.close()

        subprocess.Popen([sys.executable, "test.py"])
        print 'Test file successfully updated.'
    except Exception as e:
        print e

ftp = FTP(ip address)
ftp.login(username, password)
ftp.cwd('/Test')

ftp.retrbinary('RETR version.txt', r.write)

if(r.getvalue() != version):
    atexit.register(exithandler)
    somepid = os.getpid()
    signal.signal(SIGTERM, lambda signum, stack_frame: exit(1))
    os.kill(somepid, signal.SIGTERM)

print 'Successfully replaced and started the file'

使用:

signal.signal(SIGTERM, lambda signum, stack_frame: exit(1))

我明白了:

Traceback (most recent call last):
  File "C:\Users\STiX\Desktop\Python Keylogger\test.py", line 50, in <module>
    signal.signal(SIGTERM, lambda signum, stack_frame: exit(1))
NameError: name 'SIGTERM' is not defined

但是我完成工作没有问题,除非我在一个更复杂的脚本中使用当前代码,其中脚本给出了相同的错误但是由于某种原因立即终止。

另一方面,如果我以正确的方式signal.SIGTERM使用它,则进程直接终止并且退出函数永远不会执行。那是为什么?

如何在Windows上完成这项工作并获得上述成功的结果?

1 个答案:

答案 0 :(得分:0)

你要做的事情看起来有点复杂(从信息安全的角度来看很危险;-)。我建议处理reload-file-when-updated部分功能是添加一个控制器类,它导入你现在作为模块的python脚本,启动它并在更新时重新加载它(基于一个函数)回归或其他技术) - 以这种方式寻找灵感 - https://stackoverflow.com/a/1517072/1010991

编辑 - exe怎么办?

另一种操作当前正在运行的程序文件的hacky技术是shell ping技巧。它可以在所有编程语言中使用。诀窍是在调用进程终止之后发送一个未执行的shell命令。使用ping引起延迟并使用&amp;链接其他命令。对于您的用例,它可能是这样的:

import subprocess
subprocess.Popen("ping -n 2 -w 2000 1.1.1.1 > Nul & del hack.py & rename hack_temp.py hack.py & hack.py ", shell=True)

编辑2 - 原始问题的替代解决方案

由于python不阻止对当前运行脚本的写访问,因此解决原始问题的另一个概念是:

import subprocess
print "hello"
a = open(__file__,"r")
running_script_as_string = a.read()
b = open(__file__,"w")
b.write(running_script_as_string)
b.write("\nprint 'updated version of hack'")
b.close()
subprocess.Popen("python hack.py")