Le site arthur.bebou.netlib.re - retour accueil
git clone git://bebou.netlib.re/arthur.bebou
Log | Files | Refs |
index.sh (10400B)
1 #! page 2 title: Évaluer ses scripts en temps réel 3 author: Arthur Pons 4 description: Il est parfois fatiguant de faire l\'aller retour entre l\'écriture d\'une commande et son exécution. Créons, avec vim et/ou tmux des environnements permettant de fondre les deux 5 publication: 2024-05-09 6 7 sectionmd: main 8 9 > ATTENTION : Ce script est vraiment dangereux, ne l'utilisez pas si vous ne 10 > savez pas ce que vous faîtes. N'écrivez jamais de script contenant `rm` avec. 11 > Si vous écrivez une commande qui lit dans stdin il faudra le fermer en insérant 12 > un caractère de fin de fichier, en sortant du mode inserstion, en réinsérant un 13 > caractère de fin de fichier puis finalement en supprimant la commande qui pose 14 > souci. Vous êtes prévenu·es, c'est expérimental est tout cassé. 15 16 ## Objectif 17 18 L'objectif est d'avoir, l'un à côté de l'autre, un script et ses sorties STDERR 19 et STDOUT, en temps réel avec une mise à jour à chaque fois que l'on modifie le 20 script. Une interface comme celle-ci devrait permettre de faciliter l'écriture 21 de scripts dont la sortie nous intéresse, typiquement lorsqu'il faut traiter du 22 texte et quand itérer souvent et rapidement est souhaitable[^1]. Elle pourrait 23 également être un bon outil pour l'enseignement de `sed`, `awk`, `paste`, `cut`, 24 `tr` et toute la bande que j'aime bien. 25 26 Il n'est pas question ici d'analyser les actions du script et d'afficher en 27 français les impacts qu'il a eu sur le système (création/suppression de fichier 28 etc). Il est question de faciliter l'écriture d'une commande `sed` un peu 29 dantesque sans avoir à systématiquement exécuter le script à la main. 30 31 L'idée me vient de 32 [fzrepl](https://github.com/DanielFGray/fzf-scripts/blob/master/fzrepl) de 33 Daniel F Gray. Je voulais quelque chose de similaire mais qui fonctionne 34 pour une quantité arbitraire de commandes et éditable dans vim. 35 36 Au passage je découvre sans l'avoir prévu que ce système me permet de résoudre 37 d'une manière bien plus puissante qu'auparavant un problème que j'avais documenté 38 dans ce [vieil article](/benchmarkcatium/#et-alors-), section : 39 "L’utilisation d’éditeurs de texte s’interfaçant bien avec le système permet de 40 tester des bouts de markdown". En effet, si j'ouvre l'un des fichiers sources 41 de ce site avec la configuration vim qui va suivre j'obtiens automatiquement le 42 résultat html dans la fenêtre droite. 43 44 ## Implémentation 45 46 J'ai pour le moment la flemme de gérer les arguments de façon à faire des 47 choses différentes selon si on passe un argument un script déjà existant ou 48 pas, selon si le chemin est absolu ou relatif etc. Les scripts tels que 49 présentés en dessous vont donc systématiquement tout créer en tant que fichier 50 temporaire. Si à la fin de votre expérimentation vous voulez sauvegarder le 51 script vous pouvez toujours lancer `:w votre_script.sh`. 52 53 ### Avec vim tout seul 54 55 Commençons d'abord par créer les fichiers qui vont contenir le script et sa 56 sortie et rendre le script exécutable : 57 58 script=$(mktemp) 59 data=$(mktemp) 60 chmod +x "$script" 61 62 Vient ensuite l'ouverture de vim et sa configuration : 63 64 vim -c "set autowrite"\ 65 -c "autocmd TextChanged * silent! !$script > $data 2>&1"\ 66 -c "autocmd TextChangedI * silent! !$script > $data 2>&1"\ 67 -c "vnew $data"\ 68 -c "set updatetime=100 | set autoread | autocommand CursorHoldI * checktime | autocommand CursorHold * checktime"\ 69 -c "wincmd h | doautocmd TextChanged"\ 70 "$script" 71 72 Vim est appelé avec tout un tas de commandes suivant l'option `-c` qui 73 s'exécuteront automatiquement au lancement. Le denier argument est le chemin 74 vers le script. 75 76 Expliquons chacune des commandes vim : 77 78 * `set aw` : le fichier sera automatiquement écrit à chaque fois qu'une 79 commande externe sera lancée 80 * `autocmd TextChanged * silent! !$script > $data 2>&1` : A chaque fois que 81 le texte change en mode normal on exécute, en ignorant sa sortie et ses 82 erreurs éventuelles (`silent!`), le script dont on redirige tout vers le 83 fichier de sortie 84 * Idem mais en mode insertion 85 * `vnew $data` : on ouvre une fenêtre verticale avec le fichier de sortie 86 * `set updatetime=100 | set autoread | autocommand CursorHoldI * checktime | 87 autocommand CursorHold * checktime` : On modifie l'intervalle de mise à jour 88 à 100ms, on met le buffer avec e fichier de sortie en lecture automatique 89 (il se rafraichit à chaque changement), on force l'exécution de `checktime` 90 à chaque première fois que le curseur ne bouge plus pendant 100ms après 91 qu'il a bougé 92 * `wincmd h | doautocmd TextChanged` : on revient sur la fenêtre avec le 93 script et on déclenche une première fois l'un des évènements pour peupler 94 le fichier de sortie (utile si l'on ouvre un script déjà existant) 95 96 Finalement on affiche les chemins des deux fichiers temporaire quand on ferme 97 vim au cas-où l'on en est besoin : 98 99 echo "script : $script" 100 echo "données : $data" 101 102 Les avantages de cette version sont de ne pas dépendre de watch ni de tmux et 103 de pouvoir parcourir la sortie dans un buffer vim avec tout ce que cela 104 implique comme possibilité. 105 106 ### Avec vim + tmux + watch 107 108 Les dépendances sont : 109 110 * Une version relativement à jour de vim (qui a les évènements `TextChanged*`) 111 * tmux 112 * watch 113 114 On commence de la même manière : 115 116 script=$(mktemp) 117 data=$(mktemp) 118 chmod +x "$script" 119 120 Puis on crée la session tmux : 121 122 tmux new \ 123 vim -c "set aw"\ 124 -c "autocmd TextChanged * silent! !$script > $data 2>&1"\ 125 -c "autocmd TextChangedI * silent! !$script > $data 2>&1"\ 126 -c "doautocmd TextChanged"\ 127 "$script"\ 128 \; split-window -h "watch -c -d -t -n 0.1 cat $data" \; select-pane -L 129 130 Finalement on affiche les chemins en sortie de session : 131 132 echo "script : $script" 133 echo "données : $data" 134 135 Les avantages sont de ne pas avoir à utiliser le hack vim un peu étrange à base 136 de CursorHold pour que tout soit à jour, de voir ce qui a été modifié en sortie 137 à l'aide de `-d` de watch et être directement déposé dans tmux ce qui peut se 138 révéler utile pour retrouver votre travail plus tard. Évidemment ce dernier 139 point n'est pas essentiel si vous avez de toute façon l'habitude d'être dans 140 une session tmux quoi qu'il arrive. 141 142 ## L'espace entre les CLI des années 80 et les GUI 143 144 Au delà des raisons évoquées [en intro](/liverepl/#objectif) j'ai une autre 145 motivation à écrire ce genre d'outils. 146 147 De nombreuses critiques sont formulées envers les interfaces en ligne de 148 commande. Même si je pense qu'elles sont parfois injustes et le fruit d'apriori 149 culturels et techniques plus que de réelles limitations qui seraient par 150 ailleurs inexistantes dans les autres formes d'interfaces, il convient 151 d'admettre que l'expérience initiale dans un terminal linux est aride. 152 [Aurélien Tabard](https://tabard.fr/) en résume bien les principales raisons : 153 154 > Si la découvrabilité est en effet un point important, la gestion des erreurs 155 > l'est tout autant. Le undo n'est pas tellement développé dans les cli, pourtant 156 > la capacité d'essai-erreur-correction est facteur d'apprentissage important 157 > (oui il y a des façons de se tromper élégamment dans un terminal, mais le jour 158 > ou tu te trompes pour une raison ou une autre, le undo n'est pas là). D'autre 159 > notions permettent comme celles de gouffre d'évaluation et d'exécution peuvent 160 > expliquer le succès des gui. Enfin la capacité des systèmes à communiquer sur 161 > ce qu'ils permettent de faire (voir [par exemple ce 162 > papier](http://jovermeulen.com/Research/FeedforwardCHI2013) sur les 163 > affordances percues et le feedforward) est peu présente dans les cli. 164 165 De fait beaucoup de personnes sont introduites aux cli via des cours, des 166 tutos, des outils ne cherchant pas à faciliter l'apprentissage et l'usage des 167 cli et tombant la tête la première dans chacun des points soulevés par 168 Aurélien. Personnellement j'ai fait mes premières années de shell en école 169 d'ingénieur sans jamais savoir que l'on pouvait chercher dans l'historique des 170 commandes avec `ctrl+r`, que beaucoup de commandes avaient des options pour 171 lister ce qu'elles allaient faire avant de les faire, que l'on pouvait mettre 172 beaucoup de couleurs dans les terminaux modernes, que l'existence des TUI 173 implique que l'on puisse faire des choses comme fzy, qu'il existait des shells 174 moins complexes que bash et avec une super auto-complétion pour un large 175 ensemble de commande ou une simple liste, même un peu indigeste, des commandes 176 généralement disponibles sur un Unix. J'ai le sentiment que la conséquence de 177 cela est que de nombreuses personnes, même dans le métier, n'ont qu'une vision 178 très limitée de ce que peuvent les cli et a fortiori des TUI qui fonctionnent 179 dans un terminal. Il est donc naturel que la plupart des personnes perçoivent 180 ces interfaces comme bloquées dans les années 70/80 et ne s'y tournent que pour 181 les usages à raison catalogués comme les plus appropriés. Et pourtant on peut 182 y mener la majorité de sa vie numérique. 183 184 Attention, contrairement à l'impression que j'ai trop souvent donné lorsque je 185 parle de ce sujet, l'idée n'est pas de tout faire dans un terminal simplement 186 parce que je kiffe le terminal. C'est parce que l'usage de GUI modernes me 187 pousse à changer mon matériel, à mettre de la distance entre les personnes qui 188 produisent les logiciels que j'utilise et moi et à cloisonner mes logiciels 189 plutôt que de les faire causer entre eux que je m'intéresse à autre chose. Ne 190 sachant pas où me tourner pour trouver une communauté et une culture 191 ingénieurale axées sur le développement de GUI sobres, interopérables et 192 techniquement simples, je me tourne vers une communauté et une culture qui, la 193 plupart du temps, regroupe toutes ces qualités, j'ai nommé celle des personnes 194 qui vivent dans un terminal Unix. 195 196 Je cherche donc, avec des outils comme celui décrit dans cet article, à montrer 197 qu'il existe un espace entre les GUI d'aujourd'hui et les CLI des années 80 198 dans lequel on peut aborder les points soulevés par Aurélien tout en profitant 199 des propriétés techniques plus avantageuses pour la sobriété de nos usages du 200 numérique. 201 202 [^1]: typiquement l'écriture d'une regex un peu complexe d'où le succès d'interfaces type [regex101](https://regex101.com/)