Je cherche un moyen de regarder par programmation la sortie d'une commande jusqu'à ce qu'une chaîne particulière soit observée, puis de quitter. C'est très similaire à cette question, mais au lieu de suivre un fichier, je veux «suivre» une commande.
Quelque chose comme:
montre -n1 my_cmd | grep -m 1 "String Im Looking For"
(Mais cela ne fonctionne pas pour moi.)
MISE À JOUR: J'ai besoin de préciser que 'my_cmd' ne produit pas de texte en continu mais doit être appelé à plusieurs reprises jusqu'à ce que la chaîne soit trouvée (c'est pourquoi j'ai pensé à la commande 'watch'). À cet égard, 'my_cmd' est comme de nombreuses autres commandes Unix telles que: ps, ls, lsof, last, etc.
tail -f
sortir un programme aussi bien qu'un fichier ... Je me trompe?Réponses:
Utilisez une boucle:
Au lieu de
:
, vous pouvez utilisersleep 1
(ou 0,2) pour alléger le processeur.La boucle s'exécute jusqu'à ce que grep trouve la chaîne dans la sortie de la commande.
-m 1
signifie "une seule correspondance suffit", c'est-à-dire que grep arrête la recherche après avoir trouvé la première correspondance.Vous pouvez également utiliser
grep -q
ce qui se ferme également après avoir trouvé la première correspondance, mais sans imprimer la ligne correspondante.la source
grep -q
ce qui est une autre option. grep se ferme après avoir trouvé la chaîne.!
annule le code de sortie du pipeline de commandesgrep -m 1
se ferme lorsque la chaîne est trouvéewatch -e
renvoie si une erreur s'est produiteMais cela peut être amélioré pour afficher réellement cette ligne correspondante, qui est jetée jusqu'à présent.
la source
watch
commande (CentOS) n'a pas le-e
drapeau (ce qui ne devrait pas vraiment avoir d'importance). Plus important encore, cependant, lorsque la chaîne est trouvée, watch continue de s'exécuter et ne se ferme pas. Il semble que quand ongrep -m
sort, ça ne fait que tuermy_cmd
, mais paswatch
.tee
pour cela, mais cela introduit une nouvelle ligne trompeuse, je ne sais pas comment contourner en ce moment:watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
watch
arrête consciencieusement de regarder quand la chaîne est trouvée, mais elle ne se termine pas tant que vous n'appuyez pas sur une touche. Si proche.Pour ceux qui ont un programme qui écrit continuellement sur stdout, tout ce que vous avez à faire est de le diriger vers grep avec l'option 'single match'. Une fois que grep trouve la chaîne correspondante, il se ferme, ce qui ferme stdout sur le processus en cours de transmission vers grep. Cet événement doit naturellement provoquer la fermeture du programme sans problème tant que le processus réécrit .
Ce qui se passera, c'est que le processus recevra un SIGPIPE lorsqu'il essaiera d'écrire dans stdout fermé après la fin de grep. Voici un exemple avec ping, qui autrement fonctionnerait indéfiniment:
Cette commande correspondra au premier «pong» réussi, puis quittera la prochaine fois qu'il
ping
essaiera d'écrire sur stdout.cependant,
Il n'est pas toujours garanti que le processus réécrira sur stdout et ne provoquera donc pas la génération d'un SIGPIPE (par exemple, cela peut se produire lors de la personnalisation d'un fichier journal). La meilleure solution que j'ai réussi à trouver pour ce scénario consiste à écrire dans un fichier; veuillez commenter si vous pensez pouvoir améliorer:
Décomposer cela:
tail -f log_file & echo $! > pid
- conserve un fichier, attache le processus à l'arrière-plan et enregistre le PID ($!
) dans un fichier. J'ai plutôt essayé d'exporter le PID vers une variable, mais il semble qu'il y ait une condition de concurrence entre ici et le moment où le PID est à nouveau utilisé.{ ... ;}
- regrouper ces commandes afin que nous puissions diriger la sortie vers grep tout en gardant le contexte actuel (aide lors de l'enregistrement et de la réutilisation des variables, mais n'a pas pu faire fonctionner cette partie)|
- diriger la sortie du côté gauche vers la sortie du côté droitgrep -m1 "find_me"
- trouver la chaîne cible&& kill -9 $(cat pid)
- force kill (SIGKILL) letail
processus après lagrep
sortie une fois qu'il trouve la chaîne correspondante&& rm pid
- supprimez le fichier que nous avons crééla source
Si
tail
ne prend pas en charge la+1f
syntaxe, essayeztail -f -n +1
. (Le lui-n +1
indique de commencer au début;tail -f
par défaut commence par les 10 dernières lignes de sortie.)la source
Ajoutez le résultat de vos appels de programme à un fichier. Ensuite,
tail -f
ce fichier. De cette façon, cela devrait fonctionner ... j'espère.Lorsque vous recommencerez à appeler ce programme, vous devrez effacer le fichier ou y ajouter du charabia juste pour qu'il ne corresponde pas tout de suite à ce que vous cherchiez.
la source