繁体   English   中英

Crontab 在树莓派上启动 python 脚本导致导入错误

[英]Crontab to launch python script on raspberry pi causes import error

我在我的树莓派上运行Ubuntu Mate 我在 Python 中写了一个 web刮板,我想每天运行一次。 我认为使用sudo crontab -e将是一个很好的方法。 我遇到的问题是当cronjob启动我的 python 脚本时,python 脚本会引发导入错误并且无法运行。 但是,当我直接从命令行执行 python 脚本时,它运行没有问题。

我读到有些人使用 shell 脚本来启动他们的 python 脚本,所以我也尝试过。 同样,当我直接从命令行执行 shell 脚本时,它按预期工作,但在由cronjob执行时不起作用。

出于测试目的,现在我每分钟都执行一次cronjob ,直到我弄清楚发生了什么。 一旦它按预期工作,我会将其执行时间更改为更接近我想要的时间。

为了让您了解我的文件是什么样子,请在下面查看。 如您所见,所有需要运行的文件都有执行权限。

web_scraper.py

#!/usr/bin/env python

import click
import logging
import os
from datetime import datetime
from bs4 import BeautifulSoup as bs
import re
import urlparse
...

启动.sh

#!/bin/bash

cd /home/elmer/

python web_scraper.py

sudo crontab -e

* * * * * sh /home/elmer/start.sh >> /home/elmer/cron.log 2>&1

cron.log

Traceback (most recent call last):
  File "web_scraper.py", line 6, in <module>
    import click

ls -lh

(py27)elmer@elmer-rpi:$ ls -lh
total 56K
-rw-rw-r-- 1 elmer elmer 2.9K Mar 17 20:38 cron.log
-rwxrwxrwx 1 elmer elmer 8.2K Mar 16 09:54 web_scraper.py
-rwxrwxrwx 1 elmer elmer   64 Mar 17 20:02 start.sh

问题是您以自己的身份运行脚本,但随后您以 root 身份将其放入 cron 中。 这两个不同的用户有非常不同的环境。

您应该只使用crontab -e而不是sudo crontab -e将其放入您自己帐户的 cron 中。 您还可以从 cron 命令行的开头删除sh ,因为这是默认设置。

如果它仍然不起作用,解决方案可能会在您的常规 shell 中echo $PYTHONPATH ,然后将该设置添加到 cron:

PYTHONPATH=/your/path/here
* * * * * python /home/elmer/web_scraper.py >> /home/elmer/cron.log 2>&1

另一个不使用sudo crontab好理由是,如果您以 root 身份运行脚本,它的任何错误都可能破坏您的系统。

我不完全知道是什么导致了这个错误,但@John Zwinck 指出的似乎是在我尝试解决这个问题几个小时后得到我支持的正确答案。

我的问题是什么

与@CurtLH 类似,我让 crontab 启动了我的 python 脚本,但引发了错误消息:find no package X。在我的情况下,它是 selenium。 进一步注意,我在基于 Debian 的 Raspbian OS 上运行它。

解决方案

首先,您要在您工作的环境中找到 Python 库/模块的路径。在我的情况下,脚本位于用户目录下。

为此,请在控制台中输入python ,以便执行以下操作:

>>> import sys
>>> sys.path

它返回一个东西列表,得到第四个应该指向你的站点包的东西。 就我而言,字符串看起来像'/home/pi/.local/lib/python3.9/site-packages'

然后我们 append 一些东西到我们的 crontab 文件中。 通过在终端中键入以下内容,您可以打开 crontab:

$ sudo crontab -e

请注意,有两个单独的 crontab 文件(在我看来)。 您可以通过在 crontab 前面键入 sudo 来访问另一个,而无需如此(对于我猜的每个用户加上 root 用户)。 进一步注意,您可以通过$ (sudo) crontab -l读取 crontab 文件。 因此,当您打开 sudo crontab 时,正如我所说的sudo crontab -e ,使用箭头键向下滚动并在底部创建一个新行,在其中添加以下内容。

*/1 * * * * PYTHONPATH=/home/pi/.local/lib/python3.9/site-packages python /home/pi/script.py

*/1 * * * *表示它应该每分钟运行一次脚本(仅用于测试)(对此有帮助的指南)。 接下来我们定义它应该搜索模块的位置。 接下来是不言自明的:使用 python 打开位于...

如果您想记录脚本中的打印内容,请添加以下最后一位:

*/1 * * * * PYTHONPATH=/home/pi/.local/lib/python3.9/site-packages python /home/pi/script.py >> /var/log/script_output.log 2>&1

事实上,您可以通过交替最后一个目录来添加它应该保存到的任何日志文件。 请注意,在运行脚本数月后,此文件可能会大幅增长。 此外,仅在您提供的 arguments 之间插入空格(no ; )到您的 crontab 文件中执行脚本的所有自动执行的那一行。

要保存并关闭 crontab 文件,请按Ctrl + X ,然后按Y并按Enter ,您将返回终端。

我希望,我可以帮助你。 :) 如果是这样,请考虑通过 Upvote 支持我。 这会让我非常高兴,因为这样我终于可以添加评论了,如果你不能添加评论,那就太可惜了。

TLDR

我将以下内容添加到我的根 crontab 文件中,可通过$ sudo crontab -e访问以每分钟执行一次脚本:

*/1 * * * * PYTHONPATH=/path/to/python/site-packages python /path/to/py-script.py >> /var/log/save_log_here.log 2>&1

使用 Python 确定指向站点包的路径:

>>> import sys
>>> sys.path

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM