Python脚本在一段时间后停止

时间:2012-12-21 23:27:54

标签: python linux crash cron debian

我有一个带有raspbian的覆盆子pi,我已经创建了一个我需要一直运行的python脚本。问题是,运行一个小时后,脚本突然停止,python进程关闭。我不知道为什么,而且我对linux很新,所以我不知道如何调试它或任何东西。我不认为这是一个内存问题,因为在while循环中我释放并重新启动所有使用的对象。如何找出问题所在,或者至少在程序停止后自动重启程序?

这是代码:

import time
import sys
import ftputil
import pygame
import pygame.camera
import logging

pygame.camera.init()
#pygame.camera.list_camera() #Camera detected or not
cam = pygame.camera.Camera("/dev/video0",(640,480))
count = 5
logging.basicConfig(filename='log.log', level=logging.INFO)
logging.info(str(time.time())+" : Script was started")

while True:
        cam.start()
        img = cam.get_image()
        pygame.image.save(img,"current.jpeg")
        cam.stop()
        host = ftputil.FTPHost(**)
        host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')
        host.close()
        if not count:
                host = ftputil.FTPHost(**)
                filename = str(time.time()) + ".jpg"
                host.upload("./current.jpeg", "/webcamarchive/"+filename, mode='b')
                host.close()
                count = 10
                logging.info(str(time.time())+": Still running")
        count -= 1
        time.sleep(3)

我从ssh运行脚本。但我想在计算机启动时启动它,我将如何做到这一点?

1 个答案:

答案 0 :(得分:1)

让我们不用担心每次启动计算机时都要运行它,直到您可以在正常的登录会话中连续运行它。

如果您ssh进入计算机并启动它,只需打开ssh会话,然后观看打印出来的内容。如果由于某种原因无法做到这一点,请通过执行操作来捕获输出,例如python foo.py >foo.out 2>foo.err而不是python.py。无论哪种方式,您都可以看到为什么它停止了,而不仅仅是知道它已停止。

您还应该查看代码中明确创建的log.log文件,以及大多数Linux发行版上的syslogs(默认情况下为/var/log/syslog),以查看是否存在相关内容。< / p>

另外,请告诉我们 你是如何“从ssh运行[ning]脚本”。如果您使用&对其进行后台处理,将其作为ssh命令等发送,则需要修改上述说明。 (但是你不必等待修改后的版本 - 只需要这一次,ssh进入正常的登录脚本,在没有后台运行的情况下运行它,并使其保持运行。)

只有到目前为止您提供的信息,我们无法准确知道发生了什么。但我的第一个猜测是你得到一个未处理的异常,你会看到异常回溯,如下所示:

Traceback (most recent call last):
  File "exc.py", line 7, in <module>
    foo()
  File "exc.py", line 5, in foo
    print(1/x)
ZeroDivisionError: integer division or modulo by zero

修复就是处理它。最微不足道的修复是这样的:

while True:
    try:
        cam.start()
        img = cam.get_image()
        pygame.image.save(img,"current.jpeg")
        cam.stop()
        host = ftputil.FTPHost(**)
        host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')
        host.close()
        if !count:
                host = ftputil.FTPHost(**)
                filename = str(time.time()) + ".jpg"
                host.upload("./current.jpeg", "/webcamarchive/"+filename, mode='b')
                host.close()
                count = 10
                logging.info(str(time.time())+": Still running")
        count -= 1
    except Exception as e:
        logging.error('Caught exception: ' + str(e))
    time.sleep(3)

但是,您最好还是查看可能遇到的各种异常,或查看实际 运行的异常 - 并在每个异常中进行相应的错误处理和登录这个地方,只能用它作为最后一个回落。

此外,您应该使用with子句而不是手动close来电。例如,如果host.upload()加注,host.close()将永远不会被调用。所以,而不是:

host = ftputil.FTPHost(**)
host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')
host.close()

这样做:

with contextlib.closing(ftputil.FTPHost(**)) as host:
    host.upload("./current.jpeg", "/domains/*/public_html/webcam.jpg", mode='b')

(许多类型甚至不需要closing,因为它们本身就是上下文管理器,所以先尝试一下 - 但是如果你得到关于ftputil.FTPHost没有{{1}的错误}}或__enter__,这就是你可以处理的方法。)