[Astuce sh]: Lancer des actions en fonction de l'exécution d…

Top Page

Reply to this message
Author: Olivier Allard-Jacquin
Date:  
To: Guilde Mailing list
Subject: [Astuce sh]: Lancer des actions en fonction de l'exécution d'un programme
    Bonsoir,

    je vous livre ici une astuce de shell sh qui m'a rendu service:
- un programme "master.sh", qui fonctionne en continu, et qui génère un 
flux de texte sur son STDOUT
- on veut pouvoir récupérer ce flux de texte, et lancer des actions en 
fonction du contenu certains lignes. C'est le rôle de "analysis.sh"


    Souvent, depuis un script sh, on lance un programme ("master") à un 
moment précis, et l'on récupère le STDOUT pour analyse. Mais la 
difficulté ici est que le programme "master" ne rend jamais la main.


    Soit le programme "master.sh". Très simple, il affiche la date/heure 
toutes les 5s:


<master.sh>
#!/bin/bash -norc

while [ 1 ]; do
     date
     sleep 5s
done
</master.sh>


    Et le programme "analysis.sh", qui est lancé par l'utilisateur:
<analysis.sh>
#!/bin/bash -norc


./master.sh | while read Message; do
     case $Message in
     *1*)
         echo "- Action AAAAAAAAA"
         ;;
     *4*)
         echo "- Action BBBBBBBBB"
         ;;
     *)
         echo "- Message: >$Message<"
         ;;
     esac
done
</analysis.sh>


    L'idée est que:
- si la date/heure contient un "1", alors l'action "AAAAAAAAA" est affichée
- si par contre elle contient un "4", alors c'est l'action "BBBBBBBBB" 
qui est affichée
- sinon, c'est l'heure (la ligne STDOUT de "master.sh") qui est affichée.


    Cela donne:
./analysis.sh
- Action AAAAAAAAA
- Message: >dim. 09 janv. 2022 22:32:03 CET<
- Message: >dim. 09 janv. 2022 22:32:08 CET<
- Action AAAAAAAAA
- Action AAAAAAAAA
- Message: >dim. 09 janv. 2022 22:32:23 CET<
- Message: >dim. 09 janv. 2022 22:32:28 CET<
- Message: >dim. 09 janv. 2022 22:32:33 CET<
- Message: >dim. 09 janv. 2022 22:32:38 CET<
- Action BBBBBBBBB
- Action BBBBBBBBB


    Ici, toute l'astuce se trouve dans:
./master.sh | while read Message; do
    echo $Message
done


    A chaque fois que "./master.sh" affiche une ligne ET UN RETOUR CHARIOT, 
le "while" prend la main, et sauve cette ligne dans "$Message", qui sera 
analysée dans la boucle "do ... done".


    J'avais initialement tenté un truc plus compliqué avec le STDOUT de 
"master.sh" qui était envoyé dans une FIFO, et récupéré par "analyse.sh" 
via un pooling toutes les quelques secondes. Mais cela consommait 
inutilement du CPU.


    Ici, tant que "./master.sh" n'envoie rien sur le STDOUT, "analyse.sh" 
ne consomme pas de CPU.


    Enfin, si "./master.sh" génère beaucoup de messages qui n'ont pas 
d'intérêt, il suffit de le piper sur un grep, afin de faire un 
pre-filtre. Exemple ci-dessous, où l'on filtre tous les messages 
contenant "5" à "9":


./master.sh | grep "[5-9]" | while read Message; do
...

    Cordialement,


                            Olivier
-- 
~~~~~~~  _____/\_____  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Phoenix /   _ \/ _   \    Olivier Allard-Jacquin
        /   / \  / \   \   Web:  http://olivieraj.free.fr/
       /___/  /  \  \___\  Mail: olivieraj@???
~~~~ /////  ///\\\  \\\\\ ~~~~~~~~~~~~~~~~~~~~~~~ Linux Powered !!