可以以优美的方式在外部终止的Python脚本

时间:2018-10-24 08:14:24

标签: python sftp paramiko

我的服务器每分钟生成约30个xml文件,我想执行sftp将文件从服务器传输到我的机器。 我想使用Paramiko进行sftp,使用以下脚本获得所需的内容:

import paramiko
import os
import time
filename = "addresses.text"
localpath= "******"
serverpath= "*******"


while True:
    try:
        current_time = time.time()
        with open(filename) as f:
            data = f.readlines()
        for ipAddr in data:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(ipAddr,username="root",password="root")
            sftp = ssh.open_sftp()
            for element in sftp.listdir(serverpath):
                if element.endswith(".xml"):
                    try:
                        print(os.stat(localpath+f))
                    except:
                        try:
                            creation_time = sftp.stat(serverpath+element).st_mtime
                            if (current_time+3400 - creation_time) / (3600) <= 1:
                                sftp.get(serverpath+element,localpath+element)
                        except:
                            print(Exception)
            sftp.close()
            ssh.close()
        for f in os.listdir(localpath):
            creation_time = os.path.getctime(localpath+f)
            print((3600+current_time - creation_time) / (3600))
            if (3600+current_time - creation_time) / (3600) >= 1.8:
                os.unlink(localpath+f)

    except OSError as e:
        print(OSError)

我想做类似start sftp.py的事情,然后在后台运行我的脚本。当我想停止连接时,只需运行stop sftp.py

1 个答案:

答案 0 :(得分:2)

通常是通过正在运行的进程将其PID存储到文件中来实现的。

然后,您可以实现另一个脚本(或现有脚本的参数-如下例所示),该脚本从文件中读取PID并终止该过程。

您甚至可以make the termination graceful

import signal
import time
import os
import sys

pidfile = "sftp.pid"

if (len(sys.argv) > 1) and (sys.argv[1] == "stop"):
    if os.path.isfile(pidfile):
        with open(pidfile, "r") as f:
            pid = int(f.read())
        print("stopping sftp process {0}".format(pid))
        os.kill(pid, signal.SIGTERM)
    else:
        print("sftp is not running")
    sys.exit()

class GracefulKiller:
    kill_now = False
    def __init__(self):
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

    def exit_gracefully(self,signum, frame):
        self.kill_now = True

if __name__ == '__main__':
    pid = os.getpid()
    print("sftp is starting with pid {0}".format(str(pid)))
    with open(pidfile, "w") as f:
        f.write(str(pid))

    killer = GracefulKiller()
    while True:
        time.sleep(1)
        print("doing something in a loop ...")
        if killer.kill_now:
            break

    print "End of the program. I was killed gracefully :)"

    os.remove(pidfile)