Python 脚本在一段时间后停止

标签 python linux crash cron debian

我有一个带有 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 运行脚本。但我想让它在计算机启动时也启动,我该怎么做?

最佳答案

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

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

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

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

关于Python 脚本在一段时间后停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13998496/

相关文章:

c# - 变量未声明或从未分配?和数据读取器不工作?

购买订阅后 iOS 应用程序在启动时崩溃,但只有在发布到 AppStore 时,TestFlight 才能正常工作

python - pyparsing:提取包含特定文本的字符串

python - 使用 pandas df 的具有多个 if 的 lambda 函数

c++ - 获取ELF中函数及相关符号的信息

linux - 根据数据包类型拆分 TTY 设备

python - 授权 python 脚本在没有 OAuth2 用户流程的情况下访问 GData API

Python列表错误,列表索引超出范围

linux - 在 sftp 命令中列出文件并以毫秒显示其时间戳的命令

c - 如何在 Linux 上检查进程的堆大小