Journal mr_freeze.sh un utilitaire de capture de commandes paramétrée

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes :
0
9
nov.
2025

Sommaire

Est-ce que les gags les moins longs notamment sur celui d'insister sur le fait que bash est un langage de programmation, ne seraient pas les plus courts ?

Et bien non.

Mi rigolade, mi sérieux, j'aimerais vous introduire à un projet pour lequel, mes connaissances que je tente toujours d'étendre jusqu'à mes limites d'incompréhension et que je viens d'atteindre, pour lequel, dis je, il y a une utilité.

Le code est ici : https://gist.github.com/jul/ef4cbc4f506caace73c3c38b91cb1ea2
et si vous faîtes ./mr_freeze.sh usage vous aurez l'aide.

Comment ça marche

Déjà le programme arrive avec son jeu de test (pour moi) dont on enregistre les sorties ainsi

./mr_freeze.sh freeze input 'a*' badass 'oh un espace'

On enregistre pour toutes les LIGNES (pas de continuation avec \ possible) avec une commande par ligne qui peut avoir une variable $A … $H permettant d'accéder à $3 … $10
les résultats des commandes et la sortie est ainsi :

✍️ recording: uname -a #immutable
✍️ recording: date # mutable
✍️ recording: slmdkfmlsfs # immutable
✍️ recording: du -sh #immutable (kof kof)
✍️ recording: du #immutable (kof kof)
✍️ recording: ls "$A" #mutable according to \$3"
✍️ recording: ssh $B  'uname -a'
✅ [replay_input] created use [./mr_freeze.sh thaw "replay_input"  "a*" "badass" "oh un espace"] to replay

et quand on entre la commande

./mr_freeze.sh thaw "replay_input"  "a*" "badass" "oh un espace"

on obtient

👌 uname -a #immutable
🔥 date # mutable 
@@ -1 +1 @@
-dim. 09 nov. 2025 14:05:01 CET
+dim. 09 nov. 2025 14:06:01 CET
👌 slmdkfmlsfs # immutable
👌 du -sh #immutable (kof kof)
👌 du #immutable (kof kof)
👌 ls "$A" #mutable according to \$3"
👌 ssh $B  'uname -a'

la date qui est mutable ayant changé on a un diff de la sortie et mieux si on entre :

./mr_freeze.sh thaw "replay_input"  "a*" "petiot"

on obtient :

👌 uname -a #immutable
🔥 date # mutable 
@@ -1 +1 @@
-dim. 09 nov. 2025 14:07:34 CET
+dim. 09 nov. 2025 14:07:46 CET
👌 slmdkfmlsfs # immutable
👌 du -sh #immutable (kof kof)
👌 du #immutable (kof kof)
👌 ls "$A" #mutable according to \$3"
🔥 ssh $B  'uname -a' 
@@ -1 +1 @@
-Linux badass 6.8.0-85-generic #85-Ubuntu SMP PREEMPT_DYNAMIC Thu Sep 18 15:26:59 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
+FreeBSD petiot 14.3-RELEASE-p5 FreeBSD 14.3-RELEASE-p5 GENERIC amd64

Ce qui est ma foi for pratique. Et en plus, j'ai pas la couleur en markdown, mais sinon la sortie du diff est colorée car JE DÉTESTE les gens en ksh/sh sous BSD … ssh. Mouhahahaha

Un petit tour des curiosités du code.

J'ai pas que coder parce que j'avais un besoin, j'avais aussi envie de m'amuser, par exemple avec cette manière particulière de gérer les espaces passés dans la ligne de commande, sur le quel je m'arrachais les cheveux (peu nombreux qui me restent) en faisant une belle pirouette planquée dans du code que je préparais pour un troll futur : faisons du fonctionnel en bash.

Donc, je suis comme tout le monde, j'ai des problèmes de quote de porc avec bash et je vais vous illustrer ça dans 2 endroits du code ::

Les entrées pareilles, pas pareilles

ici
Vous voyez le code commenté ?

if [[ "$( echo $FROM | cat - )" != "$( echo $ACTUAL | cat - )" ]]; then
#if diff -q <( echo $FROM ) <( echo $ACTUAL ); then
#if [[ "$FROM" != "$ACTUAL" ]]; then

Et ben, il môrche pô.

En fait un od -a au cul de du nous apprends que la sortie réelle contient une tabulation, mais dans le mystère des pipes et echo il est transformé en espace.

Donc je normalise les sorties en faisant un echo et un pipe par cat - qui est en fait l'identité.

Qui a dit que ce que j'ai fait été porcasse ? :D Osef, ça marche.

et je t'embrouille ni vu ni connu sur la récupération des arguments de la CLI avec des espaces


ARG=()
for v in A B C D E F G H; do
    eval $v=\"$1\";
    ARG+=("$1")
    shift
done

Alors je dois mapper les arguments de la ligne de commande à coup d'éval de $3 … $10 à $A … $H car j'ai structuré mon code en fonction (voir plus tard) et dans les fonction $3 … $10 sont masqués.

Tiens, au passage je colle ça dans un tableau (l'une des rares basheries qui est nécessaire à « programmer » facilement au même titre que les tableaux associatifs).

Et je le réutilise plus tard avec cette fumisterie de

echo "✅ [replay_${INPUT}] created use [$0 thaw \"replay_$INPUT\" $( map quote "${ARG[@]}" )] to replay"

Où la magie n'est ni dans quote, ni dans map, mais dans "${ARG[@]}"

Je vous montre au passage map et quote

map() {
    f=$1;
    shift
    while [ -n "$1" ]; do
        eval "$f" "$1"
        shift
    done

}

quote() { echo -n " \"$@\""; }

et non map quote $* en top level ne donne pas le résultat attendu, et je sais vraiment pas pourquoi.

Format « libexec »

Il est en C des objets comme curl qui selon qu'on l'appelle comme un code devient un executable, mais sinon est une librairie avec le même binaire.

Là j'ai tenté de reproduire le comportement avec une détection de sourçage pour faire un return 1 et éviter l'expérience désagréable du terminal qui quitte quand on source :) et sinon appeler les fonctions idoines avec les arguments passés.

Ainsi :

./mr_freeze.sh thaw "replay_input"  "a*" "petiot"


est équivalent à

source ./mr_freeze.sh
thaw "replay_input"  "a*" "petiot"

Et ainsi on peut utiliser le code comme un script et comme une librairie (même si je pollue un peu pas mal beaucoup le namespace).

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.