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 le Quand je cours Sans queue -f code> et
grep -q code>: p> < pré> xxx pré>
grep code> ne quitte jamais et il attend donc éternellement même si "message à continuer" est enregistré dans le fichier. p>
-F code> Il semble fonctionner bien. P> p>
6 Réponses :
une solution à votre problème serait probablement (non testé et très susceptible d'exécuter mal): p> queue -f code> lira un fichier et des lignes d'affichage ultérieurement ajoutés, il ne se terminera pas (sauf si un signal comme
sigterm code> est envoyé).
Grep code> n'est pas la partie bloquante ici,
queue -f code> est.
grep code> lira dans le tuyau jusqu'à ce qu'il soit fermé, mais il n'est jamais parce que
queue -f code> ne cesse pas et garde le tuyau ouvert.
En tant que point de détail, l'interruption, cesser et d'autres signaux arrêtez également queue -f code>. Néanmoins, votre diagnostic est essentiellement correct.
@Jonathan: Mais je suis confus après avoir lu le manuel de Grep. Avec -q code> Il est censé quitter immédiatement après la première correspondance, l'exemple de l'OP devrait-il B> 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 code> comme équivalent à
-s code> et la terminaison précoce est surprenante. Ma meilleure hypothèse est que
grep code> évite d'envoyer un Sigpipe à la queue code> 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 (
C'est parce que Lancement Le script Python bloquera le script shell jusqu'à ce que les lignes souhaitées soient visibles. P> queue code> avec l'option
-f code> (suive) ne cesse pas et continue de fournir une sortie à
grep code>. En attente de lignes dans un fichier journal serait probablement plus facile avec Perl / Python. P>
queue -f code> avec le module de sous-processus Python. Lire la sortie de
queue code> 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. P>
Je pensais poster cela comme une réponse puisqu'il explique pourquoi la commande sort après une seconde écriture dans le fichier:
En effet, queue -f code> est envoyé un
Sigpipe code> quand il essaie d'écrire une nouvelle sortie sur le tuyau après i> le lecteur sur le tuyau est sorti. Le problème avec
queue -f code> est que habituellement i> 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 Code> ne sera pas envoyé avant la tentative d'écriture ultérieure.
Après une certaine expérimentation, je pense que le problème est de la manière dont 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> bash code> attend que tous les processus d'un pipeline quittent, sous une forme ou une forme de forme.
Tail -N 300 QQQ | Grep -q retour code> sort presque à la fois. Li>
Tail -N 300 -F QQQ | Grep -q retour code> ne quitte pas. li>
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;
}
Belle analyse! Fait intéressant, Motif Grep -Q <(queue -ffilfile) code> fonctionne juste bien.
@Karolyhorvath Pourquoi n'est-ce pas encore une réponse?
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.
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: P>
Tail -N 1 -f /var/log/vmkernel.log | Grep -M 1 iommintel >> / var / journal / vmkernel.log p>
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. p>
Si vous aimez VMware PRESWELL PICKING, LIRE PLUS ICI: http://hackaday.io/project/1071-thyDra-Multihed -Virtual-ordinateur p>
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.