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 !!