无限运行服务器端python脚本?

时间:2016-02-26 08:42:34

标签: python python-2.7 loops recursion rhel

我想替换Cron Jobs以“保持”我的程序活着,因为无论是否已经调用了脚本,它都会调用每个XX间隔,从而创建重复的条目。

我调查了这个问题,并采取了一些方法。一个是修改我的程序,以便检查它是否已被调用并自行关闭。我追求的是通过execfile一遍又一遍地调用它来完全脱离Cronjob,除了以下问题之外,它正是我想要的。 RuntimeError: maximum recursion depth exceeded

有没有办法让程序保持“无限循环”而不会出现堆栈溢出?

这是我的代码,它是一个检查Mails的程序,并将它们转换为MySQL DB条目。

imap = imaplib.IMAP4(hst)

try:
   imap.login(usr, pwd)
except Exception as e:
   errormsg = e
   time.sleep(30)
   print "IMAP error: " + str(errormsg)
   execfile('/var/www/html/olotool/converter.py')
   raise IOError(e)


# Authentification & Fetch Step

while True:

    time.sleep(5)
    '''
    The script will always result in an error if there
    are no mails left to check in the inbox. It then
    goes into sleep mode and relaunches itself to check
    if new mails have arrived.
    '''
    try:
        imap.select("Inbox") # Tell Imap where to go
        result, data = imap.uid('search', None, "ALL")
        latest = data[0].split()[-1]
        result, data = imap.uid('fetch', latest, '(RFC822)')
        raw = data[0][1] # This contains the Mail Data
        msg = email.message_from_string(raw)

    except Exception as e:
        disconnect(imap)
        time.sleep(60)
        execfile('/var/www/html/olotool/converter.py')
        raise IOError(e)

2 个答案:

答案 0 :(得分:0)

我自己解决了这个问题的唯一方法就是我现在可以看到它。 首先,我在上面的代码中更改了我的异常:

except Exception as e:
    disconnect(imap)
    print "Converter: No messages left"
    raise os._exit(0) 
    # This is a special case since this Exception is
    # no error thus os._exit(0) gives no false-positives

如您所见,我现在不使用execfile。相反,我写了一个控制器脚本来检查我的converter.py的状态,如果它还没有运行则启动它:

while True:

    presL = os.popen('pgrep -lf python').read()
    print "________________________________________"
    print "Starting PIDcheck"
    print "Current Processes: " 
    print presL # Check Processes

    presRconverter = find('\d{7} python converter.py', presL)
    if presRconverter:
        # Store the PID
        convPID = find('\d{7}', presRconverter)
        print "Converter is running at PID: " + convPID

    else:
        print "PID Controller: Converter not running"
        try:
            print "PID Controller: Calling converter"
            subprocess.check_call('python converter.py', shell=True)

        except subprocess.CalledProcessError as e:
            errormsg = e
            print "Couldn't call Converter Module"
            sendMail(esender,ereceiver,esubject,etext,server)
            print "Error notification send"
            raise IOError(e)

    # If we got until here without ERROR, the call was Successfull
    print "PID Controller: Call successful"
    print "________________________________________"
    time.sleep(60)

此方法不会引发:RuntimeError: maximum recursion depth exceeded。此外,如果您使用命令nohup.out运行控制器,则会为您提供nohup python converter.py文件,您可以在其中查看错误处理的任何问题。

我希望我可以帮助任何遇到同样问题的人。

答案 1 :(得分:0)

除此之外,还可以使用子进程检查等等:

def check_mail_loop():
    imap = imaplib.IMAP4(hst)
    # Build some function to login, and, in the event of an error, sleep for n seconds and call login function again.
    imap.login(usr, pwd)

    while True:
        try:
            imap.select("Inbox")
            result, data = imap.uid('search', None, "ALL")

            if result and data:
                latest = data[0].split()[-1]
                result, data = imap.uid('fetch', latest, '(RFC822)')
                raw = data[0][1] # This contains the Mail Data
                msg = email.message_from_string(raw)
            time.sleep(5)
        except SomeRelevantException as e:
            logging.log(e)
            time.sleep(60)
            pass

如果您没有预见到某些随机错误,请使用过程控制管理器,例如supervisord或monit。