Execute o script Python via crontab

91

Estou tentando executar um script Python usando o crontab do Linux . Quero executar este script a cada 10 minutos.

Encontrei muitas soluções e nenhuma funcionou. Por exemplo: editar o anacron em /etc/cron.d ou utilização crontab -e. Eu coloco essa linha no final do arquivo, mas não muda nada. Tenho que reiniciar algum serviço?

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

Que arquivo devo editar para configurar isso?


Aqui está o roteiro.

#!/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
fonte
Quando você diz "isso não muda nada". Mostra um erro, não funciona? Qual é o comportamento?
Raul Marengo
é "Documets" em vez de "Documentos" intencional?
Raul Marengo
Simplesmente não ocorre nada. :(
guisantogui
Isso vai além do escopo da pergunta, mas o que você espera que o script "listener.py" faça? Ele faz algo que possa indicar que foi executado? Faça ps -ef | grep 'crond' em sua linha de comando para verificar se o cron está rodando.
Raul Marengo
Não, este script envia vários comandos cURL para outro computador. Quando executo o "ps -f | grep 'crond'", ele retorna: "souza 4736 3947 0 14:01 pts / 1 00:00:00 grep --color = auto crond"
guisantogui

Respostas:

131

Basta usar crontab -ee seguir o tutorial aqui.

Consulte o ponto 3 para obter um guia sobre como especificar a frequência.

Com base em seus requisitos, deve ser efetivamente:

*/10 * * * * /usr/bin/python script.py
Raul Marengo
fonte
1
Eu sigo este tutorial, mas quando salvo o arquivo aparece uma mensagem: "/tmp/crontab.JTQ0My/crontab":22: erros de minuto ruim no arquivo crontab, não é possível instalar. Quer repetir a mesma edição? (s / n) "se eu digitar" y ", volto para editar o arquivo. E se eu digitar" n ", o arquivo não é salvo. Acrescento esta linha na última linha do arquivo:" / 1 * * * * / usr / bin / python script.py "
guisantogui
@guisantogui há um ponto no tutorial que explica que o uso de "/ 1" pode não ser suportado por todos os sistemas operacionais. Em qual sistema operacional você está executando isso?
Raul Marengo
3
@guisantogui acabou de notar que falta um "*" antes do "/"
Raul Marengo
outra maneira é adicionar uma declaração env em seu script.py. Veja meus comentários sobre a solução aceita em: stackoverflow.com/questions/25633737/python-crontab-and-paths
Quetzalcoatl
E se você quiser executar script.pyapenas no diretório fornecido?
Shubham A.
68

Coloque seu script em um arquivo foo.pycomeçando com

#!/usr/bin/python

Em seguida, dê permissão de execução para esse script usando

chmod a+x foo.py

e use o caminho completo do seu foo.pyarquivo no seu crontab.

Veja a documentação do execve (2) que está lidando com o shebang .

Basile Starynkevitch
fonte
1
@Tomer Se eles forem shscripts de shell POSIX , sim. Se eles usarem recursos não padrão específicos para ksh, zshou bashentão, eles precisam ser executados usando esse shell específico.
tripleee
28

Como você mencionou, isso não muda nada .

Primeiro, você deve redirecionar a entrada padrão e o erro padrão da execução do crontab, como a seguir:

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

Em seguida, você pode visualizar o arquivo /tmp/listener.logpara ver se o script foi executado conforme o esperado.

Em segundo lugar, acho que o que você quer dizer com mudar qualquer coisa é observar os arquivos criados pelo seu programa:

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

O trabalho crontab acima não criará esses arquivos no diretório /home/souza/Documets/Listener, pois o trabalho cron não é executado neste diretório e você usa o caminho relativo no programa. Portanto, para criar esse arquivo no diretório /home/souza/Documets/Listener, o seguinte cron job resolverá o problema:

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

Mude para o diretório de trabalho e execute o script a partir daí, e então você pode ver os arquivos criados no local.

Greenqy
fonte
o que significa 2> e 1?
Mohideen bin Mohammed
1
@MohideenibnMohammed redireciona mensagens de erro ( stderr) para a linha de comando visível ( stdout)
Juha Untinen
Essa resposta é a que você deve usar se estiver usando caminhos relativos.
DaReal de
Esta resposta pode funcionar com esta: stackoverflow.com/questions/65586171/… ?
Devilhorn