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()

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

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


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.


¿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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.