Comment exécuter une commande dans une boucle jusqu'à ce que je vois une chaîne dans stdout?
Je suis sûr qu'il ya quelques trivial one-liner avec perl, ruby, bash, peu importe ce que cela permettez-moi de lancer une commande dans une boucle jusqu'à ce que j'observe une chaîne de caractères dans la sortie standard, puis de s'arrêter. Idéalement, j'aimerais capturer la sortie standard, mais si c'est pour de la console, cela peut être suffisant.
L'environnement particulier dans la question du moment, c'est RedHat Linux, mais ont besoin de la même chose sur Mac, parfois trop. Donc, quelque chose, générique et *nixy serait le mieux. Ne se soucient pas de Windows - sans doute un *nixy chose serait de travailler sous cygwin.
Mise à JOUR: Remarque: les "observer une chaîne de caractères" je veux dire "stdout contient une chaîne de caractères" non "stdout EST une chaîne de caractères".
source d'informationauteur Alex Miller
Vous devez vous connecter pour publier un commentaire.
En Perl:
Exemple:
Vous voudrez peut-être ajouter un sommeil de là, si.
Il y a un tas de façons de le faire, la première qui vient à l'esprit:
Où $cmd est votre commande à exécuter.
Pour le fun, voici un BASH fonction de la version, vous pouvez donc appeler cela plus facilement si c'est quelque chose que vous êtes désireux pour appeler à partir d'un shell interactif sur une base régulière:
Avertissement: peu testé, peut-être besoin de faire un peu plus d'échapper etc. si votre commande a beaucoup d'arguments pour la chaîne contient des caractères spéciaux.
MODIFIER: sur la Base des commentaires à partir d'Adam commentaire - si vous ne pas besoin de la sortie pour une raison quelconque (c'est à dire ne voulez pas afficher le résultat), alors vous pouvez utiliser cette version plus courte, avec moins d'utilisation de backticks et donc moins de frais généraux:
BASH fonction de la version aussi:
Je suis surpris, je n'ai pas vu une brève Perl one-liner mentionné ici:
Perl est vraiment une belle langue pour des trucs comme ça. Remplacer "commande" avec la commande que vous souhaitez exécuter plusieurs fois. Remplacer "recherche" avec ce que vous voulez rechercher. Si vous recherchez quelque chose avec une barre oblique, puis remettez
m/search/
avecm#search
chaîne avec/es#
.Aussi, Perl fonctionne sur beaucoup de plates-formes différentes, y compris Win32, et que cela fonctionne partout où vous avez une installation Perl. Il suffit de changer votre commande de façon appropriée.
grep -c 99999
imprime 99999 lignes de contexte pour le match (je suppose que ce sera suffisant):ou
...cela permettra d'imprimer quelques bons points pour indiquer la progression.
EDIT:
Ma réponse originale à cette question a été en supposant que "une chaîne de caractères" signifie "toute chaîne de caractère". Si vous avez besoin de regarder pour un spécifique, Perl est probablement votre meilleure option, car presque rien ne peut battre Perl quand il s'agit de l'expression rationnelle correspondant.
Toutefois, si vous ne pouvez pas utiliser Perl pour une raison quelconque (vous pouvez vous attendre à Perl d'être présent dans la plupart des distributions Linux, mais personne n'oblige l'utilisateur à l'installer, bien que Perl peut ne pas être disponible), vous pouvez le faire avec l'aide de grep. Cependant, certains de la commande grep solutions que j'ai vu jusqu'à présent ne sont pas optimales (ils sont plus lentes que celles qui seraient nécessaires). Dans ce cas, je préfère faire les suivants:
Remplacer COMMANDE avec la commande à exécuter et CHAÎNE_QUELCONQUE avec la chaîne de caractères à rechercher. Si CHAÎNE_QUELCONQUE est trouvé dans la sortie de COMMANDE, la boucle s'arrête et imprimer la sortie où CHAÎNE_QUELCONQUE a été trouvé.
RÉPONSE ORIGINALE À CETTE QUESTION:
Probablement pas la meilleure solution (je ne suis pas bon bash programmeur), mais ça marche 😛
Il suffit de remplacer XXXX par votre appel à la commande, par exemple, essayez d'utiliser "echo" et il ne reviendra jamais (comme echo jamais imprime rien à stdout), toutefois, si vous utilisez "echo test" il va mettre fin à la fois, et enfin d'imprimer test.
La commande tee pouvez capturer la sortie standard dans un tuyau tout en encore de transmettre les données sur, et
-a
fait ajouter dans le fichier au lieu de l'écraser à chaque fois.grep -q
serareturn 0
si il y avait un match,1
autrement et de ne rien écrire sur la sortie standard stdout.$?
est la valeur de retour de la commande précédente, de sorte$CONT
sera la valeur de retour de grep dans ce cas.Une façon simple de le faire ce serait
Les backticks autour de la commande de rendre les
until
de test pour certains sortie pour être retourné plutôt que de tester la valeur de sortie de la commande.