10
votes

'grep -q' ne pas sortir avec "queue -f"

J'essaie d'implémenter un script qui attend un message spécifique dans un fichier journal. Une fois que le message est enregistré, je veux continuer le script.

Voici ce que j'essaie avec queue -f et grep -q : < pré> xxx

le grep ne quitte jamais et il attend donc éternellement même si "message à continuer" est enregistré dans le fichier.

Quand je cours Sans -F Il semble fonctionner bien.


1 commentaires

Cela pourrait être lié à la mise en mémoire tampon dans la queue. Lorsque j'exécute votre commande, il ne fonctionne pas, mais la sortie après une autre écrit dans le fichier.


6 Réponses :


11
votes

queue -f lira un fichier et des lignes d'affichage ultérieurement ajoutés, il ne se terminera pas (sauf si un signal comme sigterm est envoyé). Grep n'est pas la partie bloquante ici, queue -f est. grep lira dans le tuyau jusqu'à ce qu'il soit fermé, mais il n'est jamais parce que queue -f ne cesse pas et garde le tuyau ouvert.


une solution à votre problème serait probablement (non testé et très susceptible d'exécuter mal): xxx


5 commentaires

En tant que point de détail, l'interruption, cesser et d'autres signaux arrêtez également queue -f . Néanmoins, votre diagnostic est essentiellement correct.


@Jonathan: Mais je suis confus après avoir lu le manuel de Grep. Avec -q Il est censé quitter immédiatement après la première correspondance, l'exemple de l'OP devrait-il fonctionner. Grep quitte et arrêtez de lire du tuyau


Oui, moi aussi ... je suis perplexe à ce sujet. C'est un «nouveau» comportement pour moi; Je me souviens de -q comme équivalent à -s et la terminaison précoce est surprenante. Ma meilleure hypothèse est que grep évite d'envoyer un Sigpipe à la queue en continuant à lire, mais je n'ai pas prouvé cela. (J'allais modifier mon commentaire pour supprimer la deuxième phrase, mais je n'y suis pas arrivé à temps.)


En outre, cela n'explique pas pourquoi si vous écrivez une deuxième ligne dans le fichier (après le message d'arrêt) - même un "\ n" - il va sortir comme censé. Cela m'implique que Grep -q se comportera dans la manière dont l'OP s'attend à mais il y a une autre étrangeté avec la mise en mémoire tampon.


En tant que point de référence, cette commande se comporte de manière identique aux opérations ops: queue -f xxx | perl -e 'alors que () {sortie si / stop /}'. Ce qui est de dire qu'il sort correctement seulement après la deuxième écriture.



0
votes

C'est parce que queue avec l'option -f (suive) ne cesse pas et continue de fournir une sortie à grep . En attente de lignes dans un fichier journal serait probablement plus facile avec Perl / Python.

Lancement queue -f avec le module de sous-processus Python. Lire la sortie de queue dans une boucle jusqu'à ce que vous voyiez les lignes souhaitées, quittez le script Python. Mettre cette solution à l'intérieur de votre script shell.

Le script Python bloquera le script shell jusqu'à ce que les lignes souhaitées soient visibles.


0 commentaires

1
votes

Je pensais poster cela comme une réponse puisqu'il explique pourquoi la commande sort après une seconde écriture dans le fichier: xxx


1 commentaires

En effet, queue -f est envoyé un Sigpipe quand il essaie d'écrire une nouvelle sortie sur le tuyau après le lecteur sur le tuyau est sorti. Le problème avec queue -f est que habituellement la "queue" d'un fichier correspondra à une seule écriture à un tuyau et même si le lecteur lit uniquement le premier octet et Sorties, Sigpipe ne sera pas envoyé avant la tentative d'écriture ultérieure.



4
votes

Après une certaine expérimentation, je pense que le problème est de la manière dont bash code> attend que tous les processus d'un pipeline quittent, sous une forme ou une forme de forme.

avec un fichier simple 'QQQ 'De quelque 360 ​​lignes de Source C (une variété de programme a concaté plusieurs fois) et en utilisant' Grep -q retour ', alors j'observe: p>

  1. Tail -N 300 QQQ | Grep -q retour code> sort presque à la fois. Li>
  2. Tail -N 300 -F QQQ | Grep -q retour code> ne quitte pas. li>
  3. Tail -N 300 -F QQQ | strace -o grep.strace -q retour code> ne quitte pas avant l'interruption. Le fichier grep.strace code> se termine par: p>

    #define _XOPEN_SOURCE 600
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdarg.h>
    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    
    static void err_error(const char *fmt, ...)
    {
        int errnum = errno;
        va_list args;
        va_start(args, fmt);
        vfprintf(stderr, fmt, args);
        va_end(args);
        if (errnum != 0)
            fprintf(stderr, "%d: %s\n", errnum, strerror(errnum));
        exit(1);
    }
    
    int main(void)
    {
        int p[2];
        if (pipe(p) != 0)
            err_error("Failed to create pipe\n");
        pid_t pid;
        if ((pid = fork()) < 0)
            err_error("Failed to fork\n");
        else if (pid == 0)
        {
            char *tail[] = { "tail", "-f", "-n", "300", "qqq", 0 };
            dup2(p[1], 1);
            close(p[0]);
            close(p[1]);
            execvp(tail[0], tail);
            err_error("Failed to exec tail command");
        }
        else
        {
            char *grep[] = { "grep", "-q", "return", 0 };
            dup2(p[0], 0);
            close(p[0]);
            close(p[1]);
            execvp(grep[0], grep);
            err_error("Failed to exec grep command");
        }
        err_error("This can't happen!\n");
        return -1;
    }
    


2 commentaires

Belle analyse! Fait intéressant, Motif Grep -Q <(queue -ffilfile) fonctionne juste bien.


@Karolyhorvath Pourquoi n'est-ce pas encore une réponse?



4
votes
tail -f logfile | grep  --max-count=1  -q 'Message to continue'
Admittedly, it exits when the next line is read, not immediately on the matched one.

0 commentaires

0
votes

Je cherchais la réponse à cela pour mon propre projet. Essayer de tester quand exactement le GPU transmis est actif sur un VMware ESXI VM. Plusieurs variations de la même question sont partout. Celui-ci est assez récent. J'ai trouvé un moyen de le tromper et si vous pouvez vivre avec votre ligne intéressante répétée dans le journal, alors:

Tail -N 1 -f /var/log/vmkernel.log | Grep -M 1 iommintel >> / var / journal / vmkernel.log

Cette queue le journal, une ligne à la fois, Grep vérifie chaque ligne pour la première occurrence et l'a ajouté à la queue que la queue quitte immédiatement.

Si vous aimez VMware PRESWELL PICKING, LIRE PLUS ICI: http://hackaday.io/project/1071-thyDra-Multihed -Virtual-ordinateur


0 commentaires