Wykonaj skrypt Pythona przez crontab

90

Próbuję wykonać skrypt w języku Python przy użyciu tabeli crontab systemu Linux. Chcę uruchamiać ten skrypt co 10 minut.

Znalazłem wiele rozwiązań i żadne z nich nie działa. Na przykład: edytuj anacron w /etc/cron.d lub użyj crontab -e. Umieściłem tę linię na końcu pliku, ale to niczego nie zmienia. Czy muszę ponownie uruchamiać jakąkolwiek usługę (y)?

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

Jaki plik muszę edytować, aby to skonfigurować?

Z góry dziękuję


Oto scenariusz.

#!/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()
guisantogui
źródło
Kiedy mówisz „to niczego nie zmienia”. Czy pokazuje błąd, czy nie działa? Jakie jest zachowanie?
Raul Marengo
czy „Documets” zamiast „Documents” jest zamierzone?
Raul Marengo
Po prostu nic się nie dzieje. :(
guisantogui
To wykracza poza zakres pytania, ale czego oczekujesz od swojego skryptu „listener.py”? Czy robi coś, co mogłoby wskazywać, że działa? Wykonaj ps -ef | grep 'crond' w linii poleceń, aby sprawdzić, czy cron działa.
Raul Marengo
Nie, ten skrypt wysyła kilka poleceń cURL do innego komputera. Kiedy wykonuję polecenie „ps -f | grep 'crond'”, zwraca to: „souza 4736 3947 0 14:01 pts / 1 00:00:00 grep --color = auto
crond

Odpowiedzi:

131

Po prostu użyj crontab -ei postępuj zgodnie z samouczkiem tutaj.

W punkcie 3 znajdziesz przewodnik dotyczący określania częstotliwości.

W oparciu o Twoje wymagania powinno to być:

*/10 * * * * /usr/bin/python script.py
Raul Marengo
źródło
1
Postępuję zgodnie z tym samouczkiem, ale kiedy zapisuję plik, pojawia się komunikat: „/tmp/crontab.JTQ0My/crontab":22: złe minuty błędów w pliku crontab, nie można zainstalować. Czy chcesz ponowić tę samą edycję? (t / n) "jeśli wpiszę" y ", wróciłem do edycji pliku. Jeśli wpiszę" n ", plik nie zostanie zapisany. Dodaję tę linię w ostatnim wierszu pliku:" / 1 * * * * / usr / bin / python script.py "
guisantogui
@guisantogui jest punkt w samouczku, który wyjaśnia, że ​​używanie „/ 1” może nie być obsługiwane przez wszystkie systemy operacyjne. Na jakim systemie operacyjnym to działa?
Raul Marengo
3
@guisantogui właśnie zauważył, że brakuje znaku „*” przed „/”
Raul Marengo
innym sposobem jest dodanie deklaracji env do pliku script.py. Zobacz moje komentarze do zaakceptowanego rozwiązania pod adresem: stackoverflow.com/questions/25633737/python-crontab-and-paths
Quetzalcoatl
A co jeśli chcesz wykonać script.pytylko w podanym katalogu?
Shubham A.
66

Umieść skrypt w pliku foo.pyzaczynającym się od

#!/usr/bin/python

następnie zezwól na wykonanie tego skryptu za pomocą

chmod a+x foo.py

i użyj pełnej ścieżki do foo.pypliku w swoim crontab.

Zobacz dokumentację execve (2), która obsługuje shebang

Basile Starynkevitch
źródło
1
@Tomer Jeśli są to shskrypty powłoki POSIX, to tak. Jeśli używają niestandardowych funkcji specyficznych dla ksh, zshlub bashmuszą być uruchamiane przy użyciu tej konkretnej powłoki.
tripleee
25

Jak wspomniałeś , niczego nie zmienia ,

Po pierwsze, powinieneś przekierować zarówno stdin, jak i stderr z wykonania crontab, jak poniżej:

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

następnie możesz wyświetlić plik, /tmp/listener.logaby sprawdzić, czy skrypt został wykonany zgodnie z oczekiwaniami.

Po drugie, zgadnij, co masz na myśli, aby zmienić cokolwiek , obserwując pliki utworzone przez program:

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

powyższe zadanie crontab nie utworzy tych plików w katalogu /home/souza/Documets/Listener, ponieważ zadanie cron nie jest wykonywane w tym katalogu i używasz ścieżki względnej w programie. Aby utworzyć ten plik w katalogu /home/souza/Documets/Listener, następujące zadanie cron załatwi sprawę:

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

Przejdź do katalogu roboczego i wykonaj skrypt z tego miejsca, a następnie możesz przeglądać pliki utworzone w miejscu.

greenqy
źródło
co oznacza 2> i 1?
Mohideen bin Mohammed
1
@MohideenibnMohammed przekierowuje komunikaty o błędach ( stderr) do widocznego wiersza poleceń ( stdout)
Juha Untinen
Ta odpowiedź jest tą, której powinieneś użyć, jeśli używasz ścieżek względnych.
DaReal