Выполнить скрипт Python через crontab


91

Я пытаюсь выполнить сценарий Python с помощью Linux crontab . Я хочу запускать этот скрипт каждые 10 минут.

Я нашел много решений, и ни одно из них не сработало. Например: отредактируйте анакрон в /etc/cron.d или используйте 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()

Когда вы говорите «это ничего не меняет». Выдает ошибку, не запускается? Какое поведение?
Рауль Маренго

"Documets" вместо "Documents" намеренно?
Рауль Маренго

Просто ничего не происходит. :(
guisantogui 04

Это выходит за рамки вопроса, но что вы ожидаете от вашего скрипта "listener.py"? Делает ли он что-нибудь, что могло бы указывать на его запуск? Сделайте ps -ef | grep 'crond' в командной строке, чтобы проверить, запущен ли cron.
Рауль Маренго

Нет, этот сценарий отправляет несколько команд cURL на другой компьютер. Когда я выполняю «ps -f | grep 'crond'», он возвращает следующее: «souza 4736 3947 0 14:01 pts / 1 00:00:00 grep --color = auto crond»
guisantogui

Ответы:


131

Просто используйте crontab -eи следуйте инструкциям здесь.

См. Пункт 3, чтобы узнать, как указать частоту.

Исходя из ваших требований, он должен быть:

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

1
Я следую этому руководству, но когда я сохраняю файл, появляется сообщение: «/tmp/crontab.JTQ0My/crontab »:22: ошибки плохих минут в файле crontab, не удается установить. Вы хотите повторить то же изменение? (y / n) «если я наберу« y », я вернусь к редактированию файла. А если я наберу« n », файл не будет сохранен. Я добавляю эту строку в последнюю строку файла:« / 1 * * * * / usr / bin / python script.py "
guisantogui

@guisantogui есть пункт в руководстве, который объясняет, что использование "/ 1" может поддерживаться не всеми операционными системами. В какой операционной системе вы это используете?
Рауль Маренго

3
@guisantogui только что заметил, что у вас отсутствует «*» перед «/»
Рауль Маренго

другой способ - добавить объявление env в ваш script.py. Мои комментарии к принятому решению см. По адресу: stackoverflow.com/questions/25633737/python-crontab-and-paths
Quetzalcoatl

Что, если вы хотите выполнить script.pyтолько в заданном каталоге?
Шубхам А.

68

Поместите свой скрипт в файл, foo.pyначинающийся с

#!/usr/bin/python

Затем дайте разрешение на выполнение этому сценарию, используя

chmod a+x foo.py

и используйте полный путь к вашему foo.pyфайлу в вашем crontab.

См. Документацию execve (2), которая обрабатывает shebang .


1
@Tomer Если это shсценарии оболочки POSIX, то да. Если они используют нестандартные возможности , специфичные для ksh, zshили bashто они должны быть выполнены с помощью этой конкретной оболочки.
Tripleee

28

Как вы уже сказали, это ничего не меняет .

Во-первых, вы должны перенаправить стандартный ввод и стандартную ошибку из выполнения 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?
Мохидин бин Мохаммед

1
@MohideenibnMohammed перенаправляет сообщения об ошибках ( stderr) в видимую командную строку ( stdout)
Юха Унтинен

Этот ответ следует использовать, если вы используете относительные пути.
DaReal

Может ли этот ответ работать на этот: stackoverflow.com/questions/65586171/… ?
Devilhorn
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.