我有一个带有 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/