23 votes

Tuer le programme après qu'il ait sorti une ligne donnée, depuis un Shell Shell.

Le contexte :

J'écris un test script pour un logiciel de biologie computationnelle. Le logiciel que je teste peut prendre des jours, voire des semaines, pour s'exécuter, il a donc une fonctionnalité de récupération intégrée, en cas de plantage du système ou de coupure de courant.

J'essaie de trouver comment tester le système de récupération. Plus précisément, je n'arrive pas à trouver un moyen de "planter" le programme de manière contrôlée. Je pensais en quelque sorte programmer une instruction SIGKILL pour qu'elle soit exécutée après un certain temps. Ce n'est probablement pas l'idéal, car il n'est pas garanti que le scénario de test s'exécute à la même vitesse à chaque fois (il s'exécute dans un environnement partagé), et il serait donc difficile de comparer les journaux aux résultats souhaités.

Ce logiciel IMPRIME une ligne pour chaque section d'analyse qu'il complète.

Pregunta:

Je me demandais s'il existait un moyen bon/élégant (dans un Shell Shell) de capturer la sortie d'un programme puis de tuer le programme lorsqu'une ligne/# de lignes donnée est sortie par le programme ?

16voto

spong Points 875

Si votre programme se termine sur SIGPIPE (ce qui est l'action par défaut), il devrait être suffisant de diriger la sortie vers un lecteur qui se terminera à la lecture de cette ligne.

Cela peut donc être aussi simple que

$ program | sed -e '/Suitable text from the line/q'

Si vous voulez supprimer la sortie par défaut, utilisez

$ program | sed -n -e '/Suitable text from the line/q'

De même, si l'on veut s'arrêter après un certain nombre de lignes, on peut utiliser head à la place de sed, par ex.

$ program | head -n$NUMBER_OF_LINES_TO_STOP_AFTER

L'heure exacte à laquelle le meurtre a lieu fait dépendent du comportement de mise en mémoire tampon du terminal comme le suggère stardt dans les commentaires.

12voto

Bakuriu Points 592

Une enveloppe script comme celle-ci est une approche standard. Le script exécute le programme en arrière-plan puis boucle, vérifiant le fichier journal toutes les minutes pour une certaine chaîne. Si la chaîne est trouvée, le programme en arrière-plan est tué et le script s'arrête.

command="prog -foo -whatever"
log="prog.log"
match="this is the what i want to match"

$command > "$log" 2>&1 &
pid=$!

while sleep 60
do
    if fgrep --quiet "$match" "$log"
    then
        kill $pid
        exit 0
    fi
done

8voto

stardt Points 253

En guise d'alternative à la réponse de dmckee, les grep avec la commande -m (voir par exemple cette page de manuel ) peut également être utilisée :

compbio | grep -m 1 "Text to match"

pour s'arrêter lorsqu'une ligne correspondant au texte est trouvée ou

compbio | grep -v -m 10 "Text to match"

pour attendre 10 lignes qui ne correspondent pas au texte donné.

3voto

artworkad シ Points 15473

Vous pouvez utiliser expect(1) pour regarder le stdout d'un programme puis exécuter une action prédéfinie sur certains motifs.

#!/usr/bin/env expect

spawn your-program -foo -bar 
expect "I want this text" { close }

Ou une ligne unique à intégrer dans un autre script :

expect -c "spawn your-program -foo -bar; expect \"I want this text\" { close }"

Notez que expect n'est pas fournie par défaut avec tous les systèmes d'exploitation. Vous devrez peut-être l'installer.

1voto

pistache Points 123

Vous pouvez utiliser une instruction "while" :

Vous devez pipeter la sortie de votre logiciel (ou de ses logs) et ensuite, pour chaque nouvelle ligne, faire un test conditionnel, puis lancer kill -KILL. Par exemple (j'ai testé avec /var/log/messages comme fichier de log) :

tail -f /var/log/messages | while read line; do test "$line" = "THE LINE YOU WANT TO MATCH" && kill PIDTOKILL; done

Ou avec le logiciel directement :

./biosoftware | while read line; do test "$line" = "THE LINE YOU WANT TO MATCH" && kill PIDTOKILL; done

Vous devez remplacer le chemin du journal/le nom de l'application, la ligne à faire correspondre et le PID à tuer (vous pouvez également utiliser killall).

Bonne chance avec votre logiciel,

Hugo,

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X