1 votes

Problème d'exécution de script via l'onglet cron

Je suis nouveau sur Ubuntu, et c'est la première fois que j'écris une crontab, ou que j'utilise l'éditeur Nano. En fait, j'arrive à lancer un simple script en Python via une crontab, mais ノット le script Python script doit être programmé. Voici ce que j'ai fait.

Je peux exécuter ce simple script Python (appelé testChronScript.py) via la crontab :

#!/usr/bin/python
# -*- coding: utf-8 -*-

print "TESTING"
file_name = "test_outputfile.txt"
output = open(file_name, "w")
output.write("TEST")
print "DONE"

La façon dont j'ai configuré l'onglet cron et la sortie résultante ressemble à ceci :

justin@JBot:~/PycharmProjects/Quant_Local$ sudo nano runScripts.cron 
justin@JBot:~/PycharmProjects/Quant_Local$ crontab runScripts.cron
justin@JBot:~/PycharmProjects/Quant_Local$ crontab -l
41 14 * * * python testChronScript.py  > /dev/pts/19 
justin@JBot:~/PycharmProjects/Quant_Local$ TESTING
DONE

Ce script Python s'exécutera à 14 h 41, comme prévu, et créera le fichier dans le répertoire.

Aujourd'hui, le réel script J'essaie de mettre en place un crontab qui récupère les données de wikipedia et les enregistre dans la base de données. Voici le code :

#!/usr/bin/python
# -*- coding: utf-8 -*-

# Author: Justin Dano 8/6/2016
# This script was inspired by Michael Halls-Moore articles on Quantstart.com

import datetime
import lxml.html
from urllib2 import urlopen
from math import ceil
from SharedFunctionsLib import *

def scrape_sp500_symbols():
    """
    Scrape S&P500 symbols from Wikipedia page
    :return: List of current SP500 symbols
    """
    timestamp = datetime.datetime.utcnow()

    # Use libxml to scrape S&P500 ticker symbols
    page = urlopen('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
    page = lxml.html.parse(page)
    symbols_list = page.xpath('//table[1]/tr')[1:]

    # Obtain the ticker symbol, name, and sector information 
    # for each row in the S&P500 constituent table
    ticker_symbols = []
    for symbol in symbols_list:
        tds = symbol.getchildren()
        sd = {'ticker': tds[0].getchildren()[0].text,
                'name': tds[1].getchildren()[0].text,
                'sector': tds[3].text}

        # Map ticker information to the columns of our database table
        # The first value (2) represents the status id, which is set to live by default
        ticker_symbols.append((2, sd['ticker'], sd['name'],
            sd['sector'], timestamp, timestamp))

    return ticker_symbols

def filter_symbols(symbols):
    """
    If we are updating our symbols table, we do not want to
    add duplicate symbols, so here we filter out companies
    that already exist in the database.
    :param symbols: The list of symbols scraped from Wikipedia
    :return: List of symbols not yet represented in database
    """
    new_symbols = [] 
    unique_symbols = set() 

    # Attempt to get any existing ticker data
    data = retrieve_db_tickers(con)

    # Collect a set of existing tickers
    for symbol in data:
        unique_symbols.add(symbol[1])

    # Now add any additional symbols not yet included in the
    # database from the SP500 wiki page
    for s in symbols:
        if s[0] not in unique_symbols:
            print(str(s[2]) + " will be added to the database!")
            new_symbols.append(s)

    return new_symbols

def insert_sp500_symbols(symbols):
    """
    Insert any new S&P500 symbols (that do not already belong)
    into the MySQL database.
    :param symbols: List of tuples where each tuple is data for a specific company
    """
    # Create the insert query
    column_fields = "status_id, ticker, name, sector, created_date, last_updated_date"
    insert_fields = ("%s, " * 6)[:-2]
    query_string = "INSERT INTO symbol (%s) VALUES (%s)" % (column_fields, insert_fields)

    # Insert symbol data into the database for every symbol
    with con: 
        cur = con.cursor()
        # This line avoids the MySQL MAX_PACKET_SIZE
        # It chunks the inserts into sets of 100 at a time
        for i in range(0, int(ceil(len(symbols) / 100.0))):
            cur.executemany(query_string, symbols[i*100:(i+1)*100-1])

if __name__ == "__main__":
    con = get_db_connection()

    # 1.Scrape ticker data for the current companies existing in the S&P500 index from Wikipedia
    symbols = scrape_sp500_symbols()

    # 2.Filter out pre-existing data that may already belong in our database
    filtered_symbols = filter_symbols(symbols)

    # 3.Insert company ticker data into our MySQL database
    insert_sp500_symbols(filtered_symbols)

Le résultat ressemble maintenant à ceci :

justin@JBot:~/PycharmProjects/Quant_Local$ sudo nano runScripts.cron
justin@JBot:~/PycharmProjects/Quant_Local$ crontab runScripts.cron
justin@JBot:~/PycharmProjects/Quant_Local$ crontab -l
51 14 * * * python obtainSymbols.py  > /dev/pts/19 
justin@JBot:~/PycharmProjects/Quant_Local$ 

En principe, vous devriez voir des résultats supplémentaires (ainsi que de nouvelles entrées enregistrées dans la base de données). Le script semble ne pas avoir été exécuté et je n'arrive pas à comprendre pourquoi !

Voici le répertoire prouvant l'existence des fichiers dans le répertoire, et leurs permissions correspondantes.

drwxrwxr-x 3 justin justin  4096 Sep 27 14:50 .
drwxrwxr-x 4 justin justin  4096 Sep 24 14:54 ..
-rw-rw-r-- 1 justin justin  3504 Sep 25 15:02 obtainSymbols.py
-rw-r--r-- 1 root   root      52 Sep 27 14:50 runScripts.cron
-rw-rw-r-- 1 justin justin  5009 Sep 27 12:17 SharedFunctionsLib.py
-rw-rw-r-- 1 justin justin   174 Sep 25 16:56 testChronScript.py

Des suggestions sur la raison pour laquelle mon script obtainSymbols.py script n'est pas déclenché par ma crontab ? Ou toute autre suggestion sur la façon de programmer l'exécution de ce script Python (en principe tous les jours) serait d'une grande aide !

Merci pour votre temps.

0voto

Luís de Sousa Points 12652

La redirection de la sortie vers le fichier texte est incorrecte. cron exécute le script avec sh , c'est pourquoi votre cron devrait ressembler à ceci :

41 14 * * * python testChronScript.py >> /dev/pts/19 2>&1

Quand cron exécute le script, vous ne devriez pas obtenir de sortie sur la ligne de commande. A la place, vérifiez le contenu du fichier de sortie avec :

cat /dev/pts/19

De même, il est inutile de créer le runScripts.cron en tant que root.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X