【问题标题】:Crontab not executing a Python script? [duplicate]Crontab 不执行 Python 脚本? [复制]
【发布时间】: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 作业从您的主目录运行,因此您可能需要更改目录或使用完整路径名来定位数据库。

标签: python 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.dbcd 的绝对路径指向正确的目录,然后执行您的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 中使用的不一样。 解决这个问题的最简单方法是:

  1. 获取你在shell中使用的python:

$ which python # it may be "python3" or something else /usr/bin/python

  1. 在 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 pythonenv 是一个可执行文件,您必须使用“$ 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 的完整路径。

                        【讨论】:

                          猜你喜欢
                          • 2020-03-16
                          • 1970-01-01
                          • 1970-01-01
                          • 2012-02-02
                          • 2012-10-26
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2014-08-06
                          相关资源
                          最近更新 更多