Contexte:
J'écris un script de test pour un logiciel de biologie computationnelle. Le logiciel que je teste peut prendre des jours ou même des semaines pour s'exécuter, il dispose donc d'une fonctionnalité de récupération intégrée, en cas de panne du système ou de panne de courant.
J'essaie de comprendre comment tester le système de récupération. Plus précisément, je ne peux pas trouver un moyen de "planter" le programme de manière contrôlée. Je pensais en quelque sorte chronométrer une instruction SIGKILL pour qu'elle s'exécute après un certain temps. Ce n'est probablement pas idéal, car le scénario de test n'est pas garanti de fonctionner à la même vitesse à chaque fois (il s'exécute dans un environnement partagé), il serait donc difficile de comparer les journaux à la sortie souhaitée.
Ce logiciel imprime une ligne pour chaque section d'analyse qu'il effectue.
Question:
Je me demandais s'il y avait un bon moyen / élégant (dans un script shell) pour capturer la sortie d'un programme et puis tuer le programme quand une ligne / # de lignes donnée est sortie par le programme?
Réponses:
Un script wrapper comme celui-ci est une approche standard. Le script exécute le programme en arrière-plan, puis effectue une boucle, vérifiant le fichier journal toutes les minutes pour une chaîne. Si la chaîne est trouvée, le programme d'arrière-plan est supprimé et le script se ferme.
la source
Si votre programme se terminera sur SIGPIPE (qui est l'action par défaut), il devrait suffire de diriger la sortie vers un lecteur qui se terminera à la lecture de cette ligne.
Cela pourrait donc être aussi simple que
Si vous souhaitez supprimer la sortie par défaut, utilisez
De même, si l'on veut s'arrêter après un certain nombre de lignes, on pourrait utiliser la tête à la place de sed, par exemple
L'heure exacte à laquelle la destruction se produit dépend du comportement de mise en mémoire tampon du terminal, comme le suggère stardt dans les commentaires.
la source
sed
fin. OP dit "Ce logiciel imprime une ligne pour chaque section d'analyse qu'il effectue". Cela peut signifier que le programme complétera une section supplémentaire! Preuve de concept:{ echo 1; sleep 3; >&2 echo peekaboo; sleep 3; echo 2; } | sed -e '/1/q'
. Voir cette réponse . Solution possible:( program & ) | sed -e '/Suitable text from the line/q'; killall program
. Informez votre réponse de la faille et je révoquerai mon downvote.Comme alternative à la réponse de dmckee, la
grep
commande avec l'-m
option (voir par exemple cette page de manuel ) peut également être utilisée:s'arrêter lorsqu'une ligne correspondant au texte est trouvée ou
attendre 10 lignes qui ne correspondent pas au texte donné.
la source
Vous pouvez utiliser
expect(1)
pour regarder la sortie standard d'un programme, puis exécuter une action prédéfinie sur certains modèles.Ou une ligne pour l'intégration dans un autre script:
Notez que la
expect
commande n'est pas fournie avec tous les systèmes d'exploitation par défaut. Vous devrez peut-être l'installer.la source
set timeout -1
de définir un délai d'expiration indéfini, sinon tout se fermera sousexpect
le délai par défaut de 10 s.Vous pouvez utiliser une instruction "while":
Vous devez diriger la sortie de votre logiciel (ou de ses journaux) puis, pour chaque nouvelle ligne, effectuer un test conditionnel, puis exécuter kill -KILL. Par exemple (j'ai testé avec / var / log / messages comme fichier journal):
Ou directement avec le logiciel:
Vous devez remplacer le chemin du journal / le nom de l'application, la ligne à mettre en correspondance et le PID à tuer (vous pouvez également utiliser killall).
Bonne chance avec votre logiciel,
Hugo,
la source