IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Problème de lecture de stdin lors de pipe avec tail -f


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 30
    Points : 18
    Points
    18
    Par défaut Problème de lecture de stdin lors de pipe avec tail -f
    Bonjour à tous,

    Mon programme doit surveiller des lignes insérées dans des fichiers de logs et renvoyées celles qui correspondent à une expression régulière. Mon problème est que lorsque je lance mon programme de cette manière, je n'ai pas de lignes en sortie quand j'injecte des lignes dans mon fichier_log :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tail -f fichier_log | python -u mon_prog arg1 arg2
    Sachant que j'ai fait des tests en n'envoyant que des lignes correspondantes à mon expression régulière et que je n'ai pas eu de résultat alors que si je fais la même chose avec cette commande ça marche nickel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat fichier_log | python -u mon_prog arg1 arg2
    Voici mon programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #!/usr/bin/python -u
     
    import sys
    import re
    import time
     
    if len(sys.argv) != 3:
        sys.exit("You did not give the two necessary arguments.\nUsage : python ./cvfsparser.py filename VOP")
     
    file_name = sys.argv[1]
    sum_type = sys.argv[2]
    node_name = ""
    operation_type = ""
    operation_counter = ""
     
    file_name = file_name.rstrip("\n")
    sum_type = sum_type.rstrip("\n")
     
    for line in sys.stdin:
     
        line = line.rstrip("\n")
        regex="\s%s\sSUMMARY\s\[(\w+)\.\w+\]\s(\w+)\scnt\/(\d+)\s" % sum_type
        pattern = re.compile(regex)
        found = pattern.search(line)
     
        if found:
     
            node_name = found.group(1)
            operation_type = found.group(2)
            operation_counter = found.group(3)
            timestamp = time.time()
     
            print "PUTVAL %s.serveur/cvfs-%s/operations-%s %d:%s\n" % (node_name, file_name, operation_type, timestamp, operation_counter)
    Si quelqu'un a une idée sur ce que je ne fais pas correctement ou sur une manière différente de faire ça pourrait grandement m'aider.

    Merci d'avance.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 048
    Points : 1 378
    Points
    1 378
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for line in sys.stdin.readlines():

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 30
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par josmiley Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for line in sys.stdin.readlines():
    Merci, mais j'ai déjà essayé d'ajouter le readlines() et ça ne fonctionne pas. Je viens de réessayer au cas où mais ça ne donne rien.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    N'est-ce pas un problème de buffering ? Essaie de lancer Python avec l'option -u et d'utiliser readline():
    cf http://docs.python.org/using/cmdline.html#cmdoption-u

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 30
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par dividee Voir le message
    N'est-ce pas un problème de buffering ? Essaie de lancer Python avec l'option -u et d'utiliser readline():
    cf http://docs.python.org/using/cmdline.html#cmdoption-u
    Merci pour l'info c'est effectivement un problème de buffering. Cependant, j'utilise déjà l'option -u dans le shebang de mon programme. Dans la doc que tu as linké, ils parlent d'utiliser "file.readline()" pour contourner le problème rencontré avec "for line in sys.stdin", mais je vois pas comment faire ... J'ai essayé de modifier mon programme en utilisant le "file.readline()" à la place mais sans résultat. Je pense que je ne le fais pas bien.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Sans doute comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while True:
        line = file.readline()
        if not line: break
        # traitement de la ligne lue

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 30
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par dividee Voir le message
    Sans doute comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while True:
        line = file.readline()
        if not line: break
        # traitement de la ligne lue
    Merci dividee, je viens de voir ton code je ne l'ai pas testé car j'ai fait un peu autrement mais ça y ressemble et ça fonctionne. Voici le code si jamais ça peut aider quelqu'un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    line = sys.stdin.readline()
        while (line):
        line = line.rstrip("\n")
        regex="\s%s\sSUMMARY\s\[(\w+)\.\w+\]\s(\w+)\scnt\/(\d+)\s" % sum_type
        pattern = re.compile(regex)
        found = pattern.search(line)
     
        if found:
     
            node_name = found.group(1)
            operation_type = found.group(2)
            operation_counter = found.group(3)
            timestamp = time.time()
     
            print "PUTVAL %s.serveur/cvfs-%s/operations-%s %d:%s\n" % (node_name, file_name, operation_type, timestamp, operation_counter)
     
        line = sys.stdin.readline()
     
        if not line:break  #Je le rajoute d'après ce qu'à mis dividee pour être sûr de sortir

  8. #8
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Je propose de condenser ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    line = sys.stdin.readline().rstrip("\n")
    while line:
        found = re.search("\s"+sum_type+"\sSUMMARY\s\[(\w+)\.\w+\]\s(\w+)\scnt/(\d+)\s",line)
        if found:
            node_name,operation_type,operation_counter = found.groups()
            print "PUTVAL %s.serveur/cvfs-%s/operations-%s %d:%s\n" % \
                  (node_name, file_name, operation_type, time.time(), operation_counter)
        line = sys.stdin.readline().rstrip("\n")


    "\s"+sum_type+"\sSUMMARY\s\[(\w+)\.\w+\]\s(\w+)\scnt/(\d+)\s"
    est plus rapide que
    "\s%s\sSUMMARY\s\[(\w+)\.\w+\]\s(\w+)\scnt\/(\d+)\s" % sum_type



    Puisque dans ton cas tu ne peux pas définir une regex (= RegexObject ) par compilation préalable, autant ne pas s’enquiquiner et perdre du temps à en créer une à chaque ligne: il faut directement écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    re.search("\s"+sum_type+"\sSUMMARY\s\[(\w+)\.\w+\]\s(\w+)\scnt/(\d+)\s",line)


    Nota: ’/’ n’est pas un caractère qui nécessite d’être échappé.



    if not line:break
    complétement inutile avec while line:
    Dans le code de dividee, c’est différent: il y a while 1.







    Dans l’esprit “éviter des assignations inutiles“, il est aussi possible de faire:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    line = sys.stdin.readline().rstrip("\n")
    while line:
        found = re.search("\s"+sum_type+"\sSUMMARY\s\[(\w+)\.\w+\]\s(\w+)\scnt/(\d+)\s",line)
        if found:
            print "PUTVAL %s.serveur/cvfs-%s/operations-%s %d:%s\n"\
                  % ('%s', file_name, '%s', time.time(), '%s')\
                  % found.groups()
        line = sys.stdin.readline().rstrip("\n")

    mais bon, ça fait deux formatages à la suite, c’est pas foudroyant d’intérêt

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 01/11/2014, 17h07
  2. Problème de lecture temps-réel à cause d'un pipe
    Par theclem35 dans le forum Shell et commandes POSIX
    Réponses: 1
    Dernier message: 04/02/2012, 13h30
  3. problème de lecture base de registre
    Par pafounet3 dans le forum MFC
    Réponses: 10
    Dernier message: 31/12/2003, 14h06
  4. [fread] Problème de lecture de buffer
    Par karl3i dans le forum C
    Réponses: 2
    Dernier message: 25/09/2003, 09h21
  5. Réponses: 4
    Dernier message: 23/07/2003, 13h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo