通过crontab执行Python脚本

111

我正在尝试使用Linux的crontab来执行Python脚本。我希望每隔10分钟运行一次这个脚本。

我找到了很多解决方案,但都没有起作用。例如:编辑/etc/cron.d中的anacron或使用crontab -e。我在文件末尾添加了这一行,但它并没有起到任何作用。我需要重新启动某些服务吗?

*/2 * * * * /usr/bin/python /home/souza/Documets/Listener/listener.py

我需要编辑哪个文件来进行配置?


这是脚本。

#!/usr/bin/python
# -*- coding: iso-8859-15 -*-

import json
import os
import pycurl
import sys
import cStringIO

if __name__ == "__main__":

    name_server_standart = "Server created by script %d"
    json_file_standart = "{ \"server\" : {  \"name\" : \"%s\", \"imageRef\" : \"%s\", \"flavorRef\" : \"%s\" } }"

    curl_auth_token = pycurl.Curl()

    gettoken = cStringIO.StringIO()

    curl_auth_token.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1")
    curl_auth_token.setopt(pycurl.POST, 1)
    curl_auth_token.setopt(pycurl.HTTPHEADER, ["X-Auth-User: cpca",
                          "X-Auth-Key: 438ac2d9-689f-4c50-9d00-c2883cfd38d0"])

    curl_auth_token.setopt(pycurl.HEADERFUNCTION, gettoken.write)
    curl_auth_token.perform()
    chg = gettoken.getvalue()

    auth_token = chg[chg.find("X-Auth-Token: ")+len("X-Auth-Token: ") : chg.find("X-Server-Management-Url:")-1]

    token = "X-Auth-Token: {0}".format(auth_token)
    curl_auth_token.close()

    #----------------------------

    getter = cStringIO.StringIO()
    curl_hab_image = pycurl.Curl()
    curl_hab_image.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7")
    curl_hab_image.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_hab_image.setopt(pycurl.HTTPHEADER, [token])

    curl_hab_image.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_hab_image.perform()
    curl_hab_image.close()

    getter = cStringIO.StringIO()

    curl_list = pycurl.Curl()
    curl_list.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers/detail")
    curl_list.setopt(pycurl.HTTPGET, 1) #tirei essa linha e funcionou, nao sei porque
    curl_list.setopt(pycurl.HTTPHEADER, [token])

    curl_list.setopt(pycurl.WRITEFUNCTION, getter.write)
    #curl_list.setopt(pycurl.VERBOSE, 1)
    curl_list.perform()
    curl_list.close()

    #----------------------------

    resp = getter.getvalue()

    con = int(resp.count("status"))

    s = json.loads(resp)

    lst = []

    for i in range(con):
        lst.append(s['servers'][i]['status'])

    for j in range(len(lst)):
        actual = lst.pop()
        print actual

        if actual != "ACTIVE" and actual != "BUILD" and actual != "REBOOT" and actual != "RESIZE":

            print "Entra no If"

            f = file('counter', 'r+w')

            num = 0
            for line in f:
                num = line

            content = int(num)+1

            ins = str(content)

            f.seek(0)
            f.write(ins)
            f.truncate()
            f.close()

            print "Contador"

            json_file = file('json_file_create_server.json','r+w')

            name_server_final = name_server_standart % content
            path_to_image = "http://192.168.100.241:8774/v1.1/nuvemcpca/images/7"
            path_to_flavor = "http://192.168.100.241:8774/v1.1/nuvemcpca/flavors/1"

            new_json_file_content = json_file_standart % (name_server_final, path_to_image, path_to_flavor)

            json_file.seek(0)
            json_file.write(new_json_file_content)
            json_file.truncate()
            json_file.close()

            print "Json File"

            fil = file("json_file_create_server.json")
            siz = os.path.getsize("json_file_create_server.json")

            cont_size = "Content-Length: %d" % siz
            cont_type = "Content-Type: application/json"
            accept = "Accept: application/json"

            c_create_servers = pycurl.Curl()

            logger = cStringIO.StringIO()

            c_create_servers.setopt(pycurl.URL, "http://192.168.100.241:8774/v1.1/nuvemcpca/servers")

            c_create_servers.setopt(pycurl.HTTPHEADER, [token, cont_type, accept, cont_size])

            c_create_servers.setopt(pycurl.POST, 1)

            c_create_servers.setopt(pycurl.INFILE, fil)

            c_create_servers.setopt(pycurl.INFILESIZE, siz)

            c_create_servers.setopt(pycurl.WRITEFUNCTION, logger.write)

            print "Teste perform"

            c_create_servers.perform()

            print logger.getvalue()

            c_create_servers.close()

令人惊讶的是,您可能没有运行cron。尝试使用 /etc/init.d/crond start 命令启动它,然后像以前一样检查进程。 - Raul Marengo
请执行 "locate crond" 或 "find / -name 'crond' . 您正在运行哪个操作系统? - Raul Marengo
不,搜索“cron.d”,我只在etc目录下得到了结果。 - guisantogui
我建议您关闭这个问题,因为它已经得到了答案,然后开一个新的问题来解决特定问题。在评论中分享链接,我会看一下。 - Raul Marengo
更简洁的 cron 故障排除技巧:https://dev59.com/uWEh5IYBdhLWcg3wKQnY - tripleee
显示剩余21条评论
3个回答

162

只需使用crontab -e命令,并按照这里的教程进行操作。

查看第3点以了解如何指定频率的指南。

根据您的要求,应该是:

*/10 * * * * /usr/bin/python script.py

1
我按照这个教程操作,但当我保存文件时出现了以下提示:“/tmp/crontab.JTQ0My/crontab”:22: bad minute errors in crontab file, can't install. Do you want to retry the same edit? (y/n)" 如果我输入“y”,则会返回到文件编辑状态。如果我输入“n”,该文件将不会被保存。我在文件的最后一行添加了以下代码: "/1 * * * * /usr/bin/python script.py" - guisantogui
3
@guisantogui刚刚注意到你在斜杠前面缺少一个*号。 - Raul Marengo
另一种方法是在您的script.py中添加一个env声明。请参见我对已接受解决方案的评论:https://dev59.com/NIPba4cB1Zd3GeqPmwuQ - Quetzalcoatl
如果您想仅在给定目录中执行 script.py 脚本,该怎么办? - Shubham A.
你能看一下这里吗:https://stackoverflow.com/questions/65586171/how-to-set-crontab-in-order-to-run-multiple-python-and-a-shell-scripts? - Devilhorn
显示剩余4条评论

77

将你的脚本放在一个名为foo.py的文件中,并以以下代码开头:

#!/usr/bin/python

然后使用以下命令为该脚本授予执行权限:

chmod a+x foo.py

在你的crontab中使用完整路径引用你的foo.py文件。

请参考处理shebangexecve(2)文档。


1
@Tomer 如果它们是 POSIX sh shell 脚本,那么可以。如果它们使用特定于 kshzshbash 的非标准功能,则需要使用该特定的 shell 运行它们。 - tripleee

40

正如您所提到的没有改变任何事情

首先,您应该像下面这样重定向crontab执行的标准输入标准错误

*/2 * * * * /usr/bin/python /home/souza/Documets/Listener/listener.py > /tmp/listener.log 2>&1

你可以查看文件 /tmp/listener.log 来查看脚本是否按照您的预期执行。

第二个问题,我猜您所说的“更改任何内容”是通过观察程序创建的文件来实现的:

f = file('counter', 'r+w')
json_file = file('json_file_create_server.json', 'r+w')

上述crontab工作不会在目录/home/souza/Documets/Listener中创建这些文件,因为cron工作没有在该目录中执行,并且您在程序中使用了相对路径。因此,要在目录/home/souza/Documets/Listener中创建此文件,可以使用以下cron工作完成:

*/2 * * * * cd /home/souza/Documets/Listener && /usr/bin/python listener.py > /tmp/listener.log 2>&1

切换到工作目录并从那里执行脚本,然后您就可以查看在该位置创建的文件。


2>&1 是什么意思? - Mohideen bin Mohammed
2
@MohideenibnMohammed 将错误消息(stderr)重定向到可见的命令行(stdout)。 - Juha Untinen
如果您正在使用相对路径,则应该使用此答案。 - DaReal
这个答案是否适用于这个问题:https://stackoverflow.com/questions/65586171/how-to-set-crontab-in-order-to-run-multiple-python-and-a-shell-scripts? - Devilhorn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接