0

我有一个带有 raspbian 的树莓派,并且我创建了一个我需要一直运行的 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 运行脚本。但是我也想让它在计算机启动时启动,我该怎么做?

4

1 回答 1

2

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

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

您还应该查看log.log您在代码中显式创建的文件,以及系统日志(/var/log/syslog默认情况下在大多数 linux 发行版上),看看那里是否有任何相关内容。

另外,请告诉我们您是如何“从 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没有__enter__or的错误__exit__,这就是你可以处理的方法。)

于 2012-12-21T23:31:41.640 回答