Crontab 不执行 Python 脚本? [复制]
Posted
技术标签:
【中文标题】Crontab 不执行 Python 脚本? [复制]【英文标题】:Crontab not executing a Python script? [duplicate] 【发布时间】:2012-09-14 02:08:16 【问题描述】:我的 python 脚本没有在我的 crontab 下运行。
我已将它放在顶部的 python 脚本中:
#!/usr/bin/python
我试过这样做:
chmod a+x myscript.py
添加到我的crontab -e
:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
* * * * * /home/me/project/myscript.py
我的 /var/log/cron 文件说:
Sep 21 11:53:02 163-dhcp /USR/SBIN/CROND[2489]: (me) CMD (/home/me/project/myscript.py)
但是我的脚本没有运行,因为当我检查我的 sql 数据库时,没有任何改变。如果我像这样直接在终端中运行它:
python /home/me/project/myscript.py
我得到了正确的结果。
这是myscript.py
:
#!/usr/bin/python
import sqlite3
def main():
con = sqlite3.connect("test.db")
with con:
cur = con.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS testtable(Id INTEGER PRIMARY KEY, Name TEXT)")
cur.execute("INSERT INTO testtable(Name) VALUES ('BoB')")
cur.execute("SELECT * FROM testtable")
print cur.fetchall()
if __name__ == "__main__":
main()
每个 cmets:是的,/usr/bin/python
存在。我也可以只使用/home/me/project/myscript.py
直接运行python 脚本。 /usr/bin/python /home/me/project/myscript.py
有效。所以我不相信这是原因?
【问题讨论】:
脚本中有什么?它是否依赖于任何环境因素? 是的,我想我们需要看看你的 myscript.py 里面 将 MAILTO 变量设置为您的用户名。然后你会在你的邮件中收到一些可能提供线索的错误消息。 您还可以验证直接使用/home/me/project/myscript.py
运行它是否有效(开头没有python
,这是cron 运行它的方式)。
test.db
是在您的主目录中还是在其他位置? cron
作业从您的主目录运行,因此您可能需要更改目录或使用完整路径名来定位数据库。
【参考方案1】:
互联网上有很多一半的答案,所以我想我会捕捉到这个以节省其他人一些时间。
首先,cronjob 在告诉您失败的地方做得很差。我建议将标准错误输出发送到这样的日志文件:
Crontab 命令:
# m h dom mon dow command
* * * * * /path/to/your_file.sh >> out.txt 2>&1
由于这很可能是以用户身份运行命令,请检查日志文件的主目录。请注意,此脚本每分钟运行一次,这有利于调试。
下一个问题是您可能有路径问题...因为脚本可能正试图从您的主目录执行。此脚本设置当前目录,将其回显到文件,然后运行您的程序。
试试这个:
脚本文件
#!/bin/sh
cd "$(dirname "$0")";
CWD="$(pwd)"
echo $CWD
python your_python_file.py
希望这可以为其他人节省一些调试时间!!!
【讨论】:
谢谢!你为我节省了大量的调试时间!!!我遇到了 cron 随机不运行的问题,这是一场噩梦。 最后一部分“2>&1”是什么意思? 我和@Nechadil 有同样的问题,2>&1
是做什么的。提前致谢!
@EnriqueBet 后来我找到了答案。检查此链接:) unix.stackexchange.com/questions/99263/…
谢谢@Nechadil!【参考方案2】:
键入时会发生什么
/home/me/project/myscript.py
进入外壳?
你能在你的 crontbb 命令中明确使用/usr/bin/python
吗?
您能否使用test.db
或cd
的绝对路径指向正确的目录,然后执行您的python 脚本?
这有助于在您的 python 中使用调试语句并记录一些数据。 Crontab 可能很难调试。
【讨论】:
哈哈,你做到了!我将 test.db 更改为使用绝对路径/home/me/project/test.db
... 并且有效!
cron 作业在/home/me
中运行,显然您想象它会在/home/me/project
中运行。只要您了解(相对路径和)cron
开始工作的位置,就不需要绝对路径。【参考方案3】:
脚本没有启动可能是因为它找不到 python 解释器。 crontab 环境可能与您使用的 shell 环境有很大不同。搜索路径可能有很大不同。 此外,您通过显式启动 python 解释器来测试您的脚本,而您希望 crontab 仅启动脚本。 我把这一行放在我的 python 脚本的顶部:
\#!/bin/env python
此行将帮助定位解释器,无论它安装在哪个目录中,只要它位于搜索路径中。
【讨论】:
我目前在 bash 中,我已经添加了您的建议#!/bin/env python
。好像没用。
首先,看看你是否有 /bin/env 或者 env 是否在不同的目录中。
启动以下命令以获得与 crontab 使用的环境相同的环境: env -i /bin/bash --noprofile --norc 然后启动您的 python 脚本,看看它为什么会失败。这应该会给你一个想法。
@shargors 我无法告诉你你的评论对我有多大帮助。在我看来,您的评论应该是公认的答案:为什么 python 脚本在 OP 案例中失败的细节并不像解决环境问题的一般方法那么重要。谢谢! :)【参考方案4】:
这通常是因为 crontab 使用的 python 和你在 shell 中使用的不一样。 解决这个问题的最简单方法是:
-
获取你在shell中使用的python:
$ which python # it may be "python3" or something else
/usr/bin/python
-
在 crontab 文件中使用特定的 python:
* * * * * /usr/bin/python test.py
还想提一下,在 shell 中使用 env -i /bin/bash --noprofile --norc
可以让您拥有与 crontab 使用的环境相同的环境,这对调试非常有帮助。
【讨论】:
【参考方案5】:通常,像这样的 crontab 问题是由 PATH 环境变量比普通用户的 PATH 环境更具限制性/不同造成的。由于您的 shell 使用 PATH 环境来查找可执行文件(例如,当您在 shell 提示符下键入“python”时在 /usr/bin 中找到 /usr/bin/python),当 PATH 缺少常见位置时,例如 /usr/ bin 或 /usr/sbin,您的 cron 作业将失败。这咬了我很多次。简单的解决方法是在需要它的任何命令之前,自己在 crontab 文件顶部附近显式设置 PATH 。因此,只需像往常一样编辑 crontab 并在顶部附近添加类似这样的内容(如果您的二进制文件不在以下路径之一中,则需要在冒号后添加):
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
或者,只需在 crontab 中使用二进制文件和脚本的绝对路径。
【讨论】:
【参考方案6】:我也遇到了同样的问题。尽管手动执行的脚本可以正常工作,但在 crontab 中,上面提到的选项根本没有工作。我已经将我的脚本从 /home/user/script_directory/ 移动到 /opt/scripts/ 并且它开始工作了。问题的可能原因应该是对位于主目录中的子文件夹的访问(读取)权限。
【讨论】:
【参考方案7】:处理此问题的最简单方法是将您的 python 安装路径添加到 shell 脚本顶部的 PATH 中。 比如:
#!/usr/bin/env bash
export PATH="path to your python installation:$PATH"
python python_file_name.py
正如@Shargors 所说,您可以通过
对其进行测试env -i /bin/bash --noprofile --norc
【讨论】:
【参考方案8】:试试这个
* * * * * cd <directory_where_python_file_is> && bin/app etc/app_defaults.yaml
cron 存在一些路径问题。因此,当您使用 python 文件移动到目录时,cron 就像魅力一样工作!
【讨论】:
【参考方案9】:如果你在 python 中使用 anaconda,那么使用的路径是:
/home/username/anaconda3/bin/python test.py
【讨论】:
【参考方案10】:虽然这里的答案清楚地描述了问题和解决方案,但我想添加另一个对我有帮助的答案。
如果您的 python 脚本正在调用数据库,那么请确保您可以在 cron 环境中正确连接到数据库(以识别 cron 环境--> https://askubuntu.com/questions/23009/reasons-why-crontab-does-not-work)。我有一个可以从 shell 运行的文件,但不能作为 crontab 运行,除非我从 python 脚本中以 root 身份连接到数据库。
【讨论】:
【参考方案11】:有时我也面临同样的问题。无论我按照这里的建议尝试什么,我都可能得不到结果。
所以我开始编写“触发”bash 脚本如下(我们将其命名为 trigger.sh):
#!/bin/bash
/full_path/python_script.py
我正在从 crontab 调用 trigger.sh,一切都很好。
编辑:当然,不要忘记执行以下操作(赋予执行权):
$chmod +x python_script.py
$chmod +x trigger.sh
【讨论】:
【参考方案12】:尝试放入你的 crontab:
* * * * * python /path/to/your/script.py
而不是
* * * * * /path/to/your/script.py
在某些环境中,shebang 行也是#!/usr/bin/env python
。 env 是一个可执行文件,您必须使用“$ which env
”知道它所在的位置。
【讨论】:
【参考方案13】: cron 用户(脚本失败时)和终端用户(脚本成功时)是否相同? 您能否将作业输出重定向到Cron Job Log - How to Log? 中提到的某个文件。我们可以看看这是否有帮助。【讨论】:
【参考方案14】:我正在处理包含 paramiko lib
的项目,当我从 cmdlin
运行 Check_.py 时,它运行良好,但是当我设置 crontab 时它失败并出现错误 no module name paramiko
。
简而言之:
- 安装了两个不同的python版本3.7和2.4,所以我用whreris python3
定位python路径/usr/local/bin/python3.7m
所以用路径替换python
可以解决问题。
示例
* * * * * cd /home/MKhair/hlthchk/BR/ && /usr/local/bin/python3.7m /home/MKhair/hlthchk/BR/Check_.py
* * * * * cd [ path-to-the-script-dir] && [path-to-python] [path-to-the-script]
【讨论】:
【参考方案15】:这可能对某人有帮助。我遇到了同样的问题(或至少是类似的问题),帮助我的是通过运行以下命令获取 Python 的路径(注意你想要使用 python、python3 等的版本):
which python3
然后,我在我的 crontab 文件中将 python3 替换为 python3 的完整路径。
【讨论】:
以上是关于Crontab 不执行 Python 脚本? [复制]的主要内容,如果未能解决你的问题,请参考以下文章