Ejecute el script de Python a través de crontab

90

Estoy tratando de ejecutar un script de Python usando el crontab de Linux. Quiero ejecutar este script cada 10 minutos.

Encontré muchas soluciones y ninguna de ellas funciona. Por ejemplo: edite el anacron en /etc/cron.d o use crontab -e. Pongo esta línea al final del archivo, pero no cambia nada. ¿Tengo que reiniciar algún servicio?

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

¿Qué archivo debo editar para configurar esto?

Gracias por adelantado


Aquí está el guión.

#!/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
fuente
Cuando dices "no cambia nada". ¿Muestra un error, no se ejecuta? Cual es el comportamiento?
Raúl Marengo
¿Es "Documets" en lugar de "Documentos" intencional?
Raúl Marengo
Simplemente no ocurre nada. :(
guisantogui
Esto va más allá del alcance de la pregunta pero, ¿qué espera que haga su script "listener.py"? ¿Hace algo que pueda indicar que se ha ejecutado? Hacer ps -ef | grep 'crond' en su línea de comando para verificar si cron se está ejecutando.
Raul Marengo
No, este script envía varios comandos de cURL a otra computadora. Cuando ejecuto "ps -f | grep 'crond'", devuelve esto: "souza 4736 3947 0 14:01 pts / 1 00:00:00 grep --color = auto crond"
guisantogui

Respuestas:

131

Solo usa crontab -ey sigue el tutorial aquí.

Consulte el punto 3 para obtener una guía sobre cómo especificar la frecuencia.

Según su requisito, debería ser efectivamente:

*/10 * * * * /usr/bin/python script.py
Raúl Marengo
fuente
1
Sigo este tutorial, pero cuando guardo el archivo aparece un mensaje: "/tmp/crontab.JTQ0My/crontab":22: errores de minutos incorrectos en el archivo crontab, no se puede instalar. ¿Quieres volver a intentar la misma edición? (y / n) "si escribo" y ", he vuelto a editar el archivo. Y si escribo" n ", el archivo no se guarda. Añado esta línea en la última línea del archivo:" / 1 * * * * / usr / bin / python script.py "
guisantogui
@guisantogui hay un punto en el tutorial que explica que el uso de "/ 1" podría no ser compatible con todos los sistemas operativos. ¿En qué sistema operativo estás ejecutando esto?
Raúl Marengo
3
@guisantogui acaba de notar que le falta un "*" antes del "/"
Raúl Marengo
otra forma es agregar una declaración env en su script.py. Vea mis comentarios sobre la solución aceptada en: stackoverflow.com/questions/25633737/python-crontab-and-paths
Quetzalcoatl
¿Qué pasa si desea ejecutar el script.pyúnico en el directorio dado?
Shubham A.
66

Pon tu secuencia de comandos en un archivo que foo.pycomience con

#!/usr/bin/python

luego otorgue permiso de ejecución a ese script usando

chmod a+x foo.py

y use la ruta completa de su foo.pyarchivo en su crontab.

Consulte la documentación de execve (2) que está manejando el shebang

Basile Starynkevitch
fuente
1
@Tomer Si son shscripts de shell POSIX, entonces sí. Si usan características no estándar específicas de ksh, zsho bashentonces deben ejecutarse usando ese shell específico.
tripleee
25

Como has mencionado no cambia nada ,

Primero, debe redirigir tanto stdin como stderr desde la ejecución de crontab como se muestra a continuación:

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

luego puede ver el archivo /tmp/listener.logpara ver si la secuencia de comandos se ejecutó como esperaba.

En segundo lugar, adivina lo que quieres decir con cambiar algo al ver los archivos creados por tu programa:

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

el trabajo crontab anterior no creará estos archivos en el directorio /home/souza/Documets/Listener, ya que el trabajo cron no se ejecuta en este directorio y usted usa la ruta relativa en el programa. Entonces, para crear estos archivos en el directorio /home/souza/Documets/Listener, el siguiente trabajo cron hará el truco:

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

Cambie al directorio de trabajo y ejecute el script desde allí, luego podrá ver los archivos creados en su lugar.

greenqy
fuente
¿Qué significan 2> & 1?
Mohideen bin Mohammed
1
@MohideenibnMohammed redirige los mensajes de error ( stderr) a la línea de comando visible ( stdout)
Juha Untinen
Esta respuesta es la que debe usar si está usando rutas relativas.
DaReal