Forum Programmation.shell tail qui ne rend pas la main

Posté par  .
Étiquettes : aucune
0
22
mar.
2008

Bonjour,



J'ai un script qui fait un tail, lit la sortie avec read dans une boucle while et fait un break après un certain nombre de lignes lues.
Sauf qu'il se passe pas mal de temps entre le break et la suite du script.



Exemple simplifié:


tail -f /var/log/syslog|while read line; do 

echo break;
break;
done;
echo breaked


En lançant ça, on se rend bien compte qu'il y a du temps entre le break et la suite. En fait il faut attendre que tail veuille écrire une nouvelle ligne pour que ça se débloque.



Sans le -f il n'y a pas ce problème, mais je voudrais les X prochaines lignes du fichier, et pas les X dernières qui sont déjà dans le fichier



Voila, si quelqu'un a la solution à ce petit problème, je suis preneur :)

  • # je comprend pas...

    Posté par  . Évalué à 2.

    si tu veux les prochaines lignes à venir...
    fais simplement
    tail -f /var/log/syslog
    • [^] # Re: je comprend pas...

      Posté par  . Évalué à 1.

      Merci pour ta réponse. En fait je veux lire x lignes, et passer à autre chose une fois les x lignes lues. Un tail -f tout seul ne se termine jamais. Mon code ressemble un peu à ça:
      tail -f /file|while read line; do
        echo "$line"
        readen=$((readen+1))
        [ $readen -ge $x ] && break;
      done|(traitement)
      Si il y a un autre moyen de faire ça je suis preneur aussi ;)
      • [^] # Re: je comprend pas...

        Posté par  . Évalué à 4.

        Je peux te proposer une solution, c'est un peu cradouille mais ça devrait marcher (je n'ai pas testé)


        la_fifo=$(mktemp)

        # on crée la copie du fichier dans la FIFO:
        mkfifo $la_fifo
        tail -f ton_fichier > $la_fifo &
        pid_copie=$!

        # On compte le nombre de lignes:
        readen=0
        cat $la_fifo | while read line; do
          echo "$line"
          readen=$(( $readen + 1 ))
          [ $readen -ge $x ] && kill $pid_copie
          # en thérorie, la fifo devrait recevoir un End-of-File
        done

        # on enlève ce qui ne sert plus:
        rm $la_fifo
        • [^] # Re: je comprend pas...

          Posté par  . Évalué à 3.

          Sinon en réfléchissant deux secondes de plus, je viens de penser à une solution super simple et nettement moins bricolée:


          readen=0
          tail -f /file | while [ $readen -ge $x ]; do
             read line
             echo "$line"
             readen=$((readen+1))
          done | (traitement)
          • [^] # Re: je comprend pas...

            Posté par  . Évalué à 1.

            Merci :)
            Ta première solution fonctionne comme je le voulais :)
            Et la deuxième tombe en fait sur le même problème, le programme attend que tail se termine de lui même avant de passer à la suite :/
      • [^] # Re: je comprend pas...

        Posté par  . Évalué à 2.

        premier probleme, tu n'interromps jamais ton tail...

        1°) tail est lancé et il envoie ce qu'il trouve dans un pipe
        2°) ce pipe boucle tant qu'il y a à lire (donc indefiniment puisque venant d'un pipe et ne sort qu'à la ligne $x

        mais comme le pipe est toujours ouvert, il realimente la boucle...
        et c'est repartit.
        • [^] # Re: je comprend pas...

          Posté par  . Évalué à 1.

          En fait je pensais bêtement que le fait de sortir du while (break) allait tuer le tail (vu que plus personne ne lit la stdout du tail), mais apparemment non, enfin pas jusqu'a ce que tail se tue de lui même quand il tente d'écrire une nouvelle ligne.
          • [^] # Re: je comprend pas...

            Posté par  . Évalué à 1.

            tu avais deja essayé la commande tail -f /fichier
            parce que tu te serais rendu compte que tail -f ne rend jamais la main

            sauf sur ctrl+c
            • [^] # Re: je comprend pas...

              Posté par  . Évalué à 2.

              Oui, je sais bien qu'il ne rend jamais la main, je pensais juste que lorsqu'on fait quelque chose comme "cmd1|cmd2", cmd1 était tué si cmd2 se terminait.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.