arthur.bebou

Le site arthur.bebou.netlib.re - retour accueil

git clone git://bebou.netlib.re/arthur.bebou
Log | Files | Refs |

index.sh (23140B)


      1 #! page
      2 title: Des services internet simples et sobres
      3 author: Arthur Pons
      4 description: Étudions comment construire et mettre en ligne des services relativement simples et sobres sur internet
      5 publication: 2024-06-10
      6 
      7 sectionmd: main
      8 
      9 Cet article n'a pas encore été relu, un peu d'indulgence :)
     10 
     11 ## Le "trop-long-j'ai-pas-lu" :
     12 
     13 Sur un système unix possédant netcat[^1] vous pouvez faire
     14 
     15     nc bebou.netlib.re 2222
     16 
     17 puis taper `h` ou `help` et avoir la liste des commandes disponibles.
     18 
     19 ## Pourquoi ?
     20 
     21 ### Les outils existants
     22 
     23 J'avais développé quelques services que des proches ou moi trouvions utiles,
     24 notamment de quoi [conjuguer](/conjugaison/), récupérer des
     25 [synonymes](/crisco-des/), faire une recherche youtube et certainement d'autres
     26 à l'avenir. Ces outils sont généralement des scripts shell de scraping assez
     27 simples, utilisés en local.  
     28 Ils se substituent à des usages inadéquats de sites web ou de
     29 recherches Google. Remplacer *"ouvrir firefox -> taper 'conjugaison manger' ->
     30 cliquer sur le premier lien qui a pas l'air de vouloir me montrer mille popups
     31 de cookies ou de newsletters -> scroller à travers la page pour trouver la
     32 ligne que je veux -> faire un copier-coller"* par *"ouvrir un terminal -> taper 'c
     33 manger je présent' -> faire un copier-coller"* ou tout autre utilisation
     34 davantage automatisée semblait opportun. On économise du temps, de la
     35 frustration, des aller-retour clavier/souris, du texte à taper, de la bande
     36 passante, des cycles cpu, de la ram et on s'offre en prime une meilleure
     37 interopérabilité avec le reste du système. Selon quelle est la source des
     38 données on se permet également de travailler en mode hors-ligne.
     39 
     40 ### Qu'est-ce que "service" convoque comme images dans ma tête ?
     41 
     42 J'ai eu plusieurs conversations avec des membres de Katzele sur le sens que l'on
     43 met derrière le mot "service" numérique. Intuitivement, en me nourrissant
     44 davantage des exemples que je trouve autour de moi que d'une réflexion
     45 proprement théorique sur le sujet, je conçois le service comme le rapport
     46 majoritaire qui existe entre les personnes détenant du matériel et des
     47 compétences techniques et les autres, souhaitant faire appel à ce matériel et
     48 ces compétences là. La première personne, généralement une entreprise, une
     49 association, un état, va à l'aide d'ingénieur·es répondre au besoin en créant
     50 un "service". Il y a mille façons de les créer, en impliquant plus ou moins
     51 les personnes qui sont en demande par exemple, ce qui donnera mille formes
     52 différentes de services mais j'ai le sentiment que dans l'ensemble quelques
     53 caractéristiques restent assez constantes. Premièrement le cadre technique dans
     54 lesquels ils s'inscrivent est, en 2024 et ce depuis des années, presque toujours
     55 le web. Deuxièmement ils semblent vouloir, parfois volontairement, tenir au
     56 à distance les personnes utilisateur·ices du fonctionnement interne du service.
     57 La première pose des questions de soutenabilité pour des raisons mille fois
     58 évoquées sur ce blog bien que l'on puisse déjà drastiquement optimiser cette
     59 variable en faisant du web "sobre" et pour peu que l'on y évolue avec un
     60 outillage radicalement différent de celui majoritaire. La seconde va à
     61 l'encontre de l'utopie technique rêvée à Katzele dans laquelle la ligne de
     62 démarcation entre celleux qui détiennent et savent manipuler les outils et
     63 celleux qui ne peuvent que les consommer ou en consommer leurs fruits serait
     64 floutée ou à minima moins épaisse, dans la limite de ce que la complexité des
     65 outils nous permet d'envisager.
     66 
     67 C'est au gré de ces pensées que je n'ai durant ces dernières années jamais
     68 sérieusement entrepris d'interfacer mes outils via du web. Je privilégiais le
     69 fait de faire des ateliers, des formations, des démos et des articles associés
     70 pour distribuer le code localement sur les machines des personnes intéressées,
     71 propager les idées et inciter les personnes à faire leurs propres versions quand
     72 elles le peuvent.
     73 
     74 Évidemment la viabilité de cette stratégie est certainement corrélée à la
     75 complexité des idées et du code en question. Plus l'outil est complexe plus il
     76 sera intéressant pour moi d'investir une unique fois du temps
     77 dans une interface web et dire aux personnes "va simplement sur telle url"
     78 plutôt que de dupliquer l'outil ou ses variantes n fois sur n machines de n
     79 copaines. De la même manière, la pertinence de la critique est corrélée à
     80 l'écart qu'il existe entre la simplicité du service rendu et la complexité de
     81 son implémentation technique. C'est pour cela que les services implémentés
     82 jusque là sont simples et requiert peu d'interactions avec l'utilisateur·ice.
     83 C'est aussi parce que je n'ai pas l'envie ni le temps de faire des choses
     84 compliquées.
     85 
     86 ### Mais l'idée fera tout de même son bout de chemin
     87 
     88 Et pourtant, pour de multiples raisons que je n'ai pas audité en profondeur,
     89 les personnes sont généralement bien plus enthousiasmées par l'idée d'avoir un
     90 service web qu'une version locale, indépendante d'un service tiers et à
     91 l'interface plus sobre. J'en prends pour exemple un atelier sur [l'ensemble de
     92 systèmes que j'utilise pour consulter des vidéos youtube](/youtube/)[^2] de plus
     93 de deux heures pendant lesquelles les échanges avaient été fréquents et de
     94 qualité. Plusieurs jours après au gré du hasard je retombe sur l'une des
     95 personnes ayant assisté à l'atelier qui partage son enthousiasme à une tierce
     96 personne autour de [l'interface web sobre de recherche
     97 youtuube](https://codemadness.org/idiotbox) et uniquement de cet aspect là. Je
     98 n'ai pas de mal à comprendre que c'était peut-être pour elle le seul outil qui
     99 se substituait directement à l'interface youtube classique sans pour autant
    100 changer ses habitudes mais j'avoue m'être dit "oh un peu dommage 😞".
    101 
    102 Alors fort de cette expérience et pour éviter de tomber dans le sophisme de la
    103 solution parfaite[^3] je me suis dit que j'allais regarder ce qu'il était
    104 possible de faire entre l'interface web simple (formulaire html + cgi) et
    105 l'outil en ligne de commande en local.
    106 
    107 ## Quelle forme pour ces services ?
    108 
    109 L'objectif est de minimiser au moins :
    110 
    111   * La dépendance à une connection internet
    112   * nombre de dépendances
    113   * l'instabilité de ces dépendances
    114   * nombre de lignes de codes de l'outil et des dépendances
    115   * nombre de personnes dans les projets de ces dépendances[^4]
    116 
    117 En permettant :
    118 
    119   * l'interopérabilité de l'outil avec des interfaces textuelles et cli
    120 
    121 ### Communiquer sur internet
    122 
    123 Sur internet les machines communiquent entre elles via des socket.
    124 Un moyen simple de créer des sockets est d'utiliser un outil fait pour qui
    125 pourra les ouvrir ou écouter dessus. `netcat-openbsd` en est un exemple.
    126 Il a l'avantage d'être relativement simple, ne faisant "que" 2340 lignes de C,
    127 dont le fichier principal a été édité par une vingtaine de personne depuis
    128 25 ans. Sans faire de revue plus détaillée[^5] j'en conclu que c'est un logiciel
    129 suffisamment stable fonctionnement et techniquement pour assurer une bonne
    130 soutenabilité. La documentation est raisonnable et présente même quelques
    131 exemples[^6]. Par exemple, pour communiquer à un serveur web, nc permet de faire
    132 passer tel quel un header HTTP et de recevoir la réponse :
    133 
    134     $ nc bebou.netlib.re 80
    135     GET / HTTP/1.1
    136     Host: arthur.bebou.netlib.re
    137 
    138     HTTP/1.1 200 OK
    139     Server: nginx/1.22.1
    140     Date: Mon, 10 Jun 2024 12:15:14 GMT
    141     Content-Type: text/html
    142     Content-Length: 5940
    143     Last-Modified: Wed, 05 Jun 2024 17:41:29 GMT
    144     Connection: keep-alive
    145     ETag: "6660a349-1734"
    146     Accept-Ranges: bytes
    147     
    148     <!DOCTYPE html>
    149     <html lang="fr">
    150     <head>
    151         <title>Unix et environnement ?</title>
    152         <link rel=stylesheet href="/style.css" />
    153         <meta charset="utf-8">
    154 	<meta name="viewport" content="width=device-width,initial-scale=1.0">
    155 	<meta name="description" content="Un blog au sujet de la culture Unix redirigée vers la diminution de l'impact environnementale du numérique" />
    156 	<meta name="author" content="Arthur Pons" />
    157 	<link rel="icon" href="/favicon.png" />
    158     [...]
    159 
    160 Au passage on voit que c'est côté serveur web qu'est géré la partie
    161 "virtual-hosting" qui, sur la base de la valeur du `Host` renverra tel site
    162 plutôt qu'un autre.
    163 
    164 Cet exemple qui paraîtra trivial pour les personnes ayant commencé à faire de
    165 l'informatique il y a plus de vingt an et un peu magique pour la plupart des
    166 autres[^7] met quelque chose en lumière : Il n'y a rien de magique dans la façon
    167 dont les machines parlent entre elles via des protocoles. D'ailleurs n'importe
    168 quoi peut s'échanger entre deux sockets. Le manuel nous enseigne que (traduit de
    169 l'anglais) :
    170 
    171 > Il est assez aisé de construire un modèle client/serveur très simple
    172 > avec nc. Dans une console écoutez sur un port donné. Par exemple :
    173 >
    174 >     $ nc -l 1234
    175 >
    176 > nc attend une connection sur le port 1234. Dans une seconde console (ou une
    177 > seconde machine) connectez vous à la machine et le port correspondant :
    178 >
    179 >     $ nc -N 127.0.0.1 1234
    180 >
    181 > Il devrait dorénavant y avoir une connection établie entre les deux ports.
    182 > Ce qui est tapé dans la seconde console sera concaténé à la première et
    183 > vice-versa.
    184 
    185 Admettons que l'on souhaite que ce que l'on tape dans la première console soit
    186 traité d'une manière ou d'une autre et nous revienne. Plusieurs versions de
    187 netcat proposent une option `-e` qui passe les données reçues à un script tier
    188 pour traitement. Ce n'est pas le cas de netcat-openbsd, il faudra donc trouver
    189 un subterfuge. Ca tombe bien, il nous est donné dans le manuel :
    190 
    191 > Il n'existe pas d'option `-c` ou `-e` dans ce netcat mais vous pouvez toujours
    192 > exécuter une commande après qu'une connection ait été établie en redirigeant
    193 > des descripteurs de fichiers. Attention, ouvrir un port et laisser n'importe
    194 > qui exécuter des commandes arbitraires sur votre serveur est DANGEREUX. Si vous
    195 > avez réellement besoin de le faire voici un exemple :
    196 >
    197 > Côté serveur :
    198 >
    199 >      $ rm -f /tmp/f; mkfifo /tmp/f
    200 >      $ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
    201 >
    202 > Côté client :
    203 >
    204 >       $ nc host.example.com 1234
    205 >       $ (shell prompt from host.example.com)
    206 
    207 L'example donne carrément un shell interactif à toute personne qui se connecte.
    208 C'est effectivement très dangeureux mais en plus ce n'est pas ce que l'on
    209 cherche à faire.
    210 
    211 ### Exécuter des commandes à distance
    212 
    213 Le serveur est déjà équipé des commandes `conjuguer`, `synonyme` etc. On
    214 cherche, en se basant sur ce que l'on a appris précédemment, à implémenter le
    215 minimum nécessaire sur le serveur pour rendre ces commandes disponibles à
    216 distance de manière non authentifiée et sécurisée. L'idée est que la
    217 construction de services sous cette forme ne nécessite presque rien de plus que
    218 de faire fonctionner les commandes associées en local contrairement à une appli
    219 web ou même un cgi.
    220 
    221 Si l'on reprend l'exemple
    222 
    223     cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
    224 
    225 on peut modifier le filtre `/bin/sh -i 2>&1` par autre chose. Si l'on veut un
    226 service qui modifie toutes les `armes` par des `fleurs` on pourra écrire :
    227 
    228     $ cat /tmp/f | sed 's/armes/fleurs/g' | nc -l 127.0.0.1 1234 > /tmp/f[^8]
    229 
    230 Ce qui donnera côté client
    231 
    232     $ nc bebou.netlib.re 1234
    233     Ils prirent les armes
    234 
    235 Ah, ça ne fonctionne pas. En effet sed, comme pleins d'autres commandes pour
    236 des raisons de performance, ne traite pas les lignes une à une mais en stocke
    237 quelques une avant de les faire passer à la moulinette. Il constitue un
    238 "buffer", on dit parfois en franglais qu'il "buffer" son entrée. Pour résoudre
    239 ce problème deux solutions. Soit l'outil intègre une option pour ne pas
    240 bufferiser (`--unbuffered` pour GNU sed) soit on utilise la commande `stdbuf`
    241 qui dira à la commande qui lui est passée en argument qu'il ne faut rien
    242 bufferiser :
    243 
    244     $ cat /tmp/f | stdbuf -o0 sed 's/armes/fleurs/g' | nc -l 127.0.0.1 1234& > /tmp/f
    245     $ nc bebou.netlib.re 1234
    246     Ils prirent les armes
    247     Ils prirent les fleurs
    248 
    249 Super ! Nous en savons plus sur comment traiter les données qui arrivent dans le
    250 socket du serveur mais nous n'avons toujours pas créé le système que nous
    251 voulions. Pour ce faire reprenons l'exemple qui était donné dans le manuel en
    252 retirant l'aspect interactif et en ajoutant stdbuf :
    253 
    254     $ cat /tmp/f | stdbuf -o0 sh | nc -l 127.0.0.1 1234& > /tmp/f
    255     $ nc bebou.netlib.re 1234
    256     date
    257     lun. 10 juin 2024 16:04:52 CEST
    258 
    259 ### Avec un peu de securité
    260 
    261 Sans pour autant récupérer un shell, nous pouvons exécuter des commandes.
    262 Pour des raisons évidentes de sécurité nous voulons restreindre ces commandes à
    263 celles que nous mettons à disposition, par exemple `conjuguer`. Pour cela nous
    264 pouvons utiliser grep pour filtrer les entrées avant de les passer à `sh` :
    265 
    266     $ cat /tmp/f | stdbuf -o0 grep -E '^conjuguer' | stdbuf -o0 sh | nc -l 127.0.0.1 1234& > /tmp/f
    267     $ nc bebou.netlib.re 1234
    268     ls
    269     conjuguer manger
    270     Indicatif     Présent           je mange
    271     Indicatif     Présent           tu manges
    272     Indicatif     Présent           il mange
    273     Indicatif     Présent           nous mangeons
    274     Indicatif     Présent           vous mangez
    275 
    276 C'est mieux, on ne peut plus exécuter d'autres commandes que conjuguer. A moins
    277 que...
    278 
    279     $ nc bebou.netlib.re 1234
    280     conjuguer;date
    281     lun. 10 juin 2024 16:05:17 CEST
    282 
    283 A mince. Le grep n'a pas retiré la ligne puisqu'elle commence bien par
    284 "conjuguer". Le shell a ensuite tenté d'exécuter `conjuguer` sans argument (en
    285 retournant certainement une erreur) puis a compris le point virgule comme
    286 délimitant une nouvelle commande, en l'occurrence `date`, qu'il a exécuté.
    287 
    288 Le `sh` du serveur sur lequel tout cela tourne est dash. J'ai donc consulté sont
    289 manuel pour connaître les caractères spéciaux :
    290 
    291 > Lexical Structure
    292 >  The shell reads input in terms of lines from a file and breaks it up into words at
    293 >  whitespace (blanks and tabs), and at certain sequences of characters that are special
    294 >  to the shell called “operators”.  There are two types of operators: control operators
    295 >  and redirection operators (their meaning is discussed later).  Following is a list of
    296 >  operators:
    297 > 
    298 >        Control operators:
    299 >              & && ( ) ; ;; | || <newline>
    300 > 
    301 >        Redirection operators:
    302 >              < > >| << >> <& >& <<- <>
    303 
    304 et
    305 
    306 > Reserved Words
    307 >  Reserved words are words that have special meaning to the shell and are recognized at
    308 >  the beginning of a line and after a control operator.  The following are reserved
    309 >  words:
    310 > 
    311 >        !       elif    fi      while   case
    312 >        else    for     then    {       }
    313 >        do      done    until   if      esac
    314 
    315 Une manière un peu bourrine mais je pense, du moins j'espère, assez fiable est
    316 de supprimer toutes les occurrences de ces mots et caractères. Nous aurions donc
    317 à minima pour les opérateurs et autres caractères importants :
    318 
    319     $ cat /tmp/f |
    320         stdbuf -o0 tr -d '$`&(;|<>' |
    321         stdbuf -o0 grep -E '^conjuguer' |
    322         stdbuf -o0 sh |
    323         nc -l 127.0.0.1 1234& > /tmp/f
    324 
    325 Je n'ai pas la certitude que cela empêche toute commande dangereuse d'arriver à
    326 la ligne `sh`. La bonne approche serait certainement de créer une commande
    327 spéciale qui parse son entrée et sur la base de certains critères exécute
    328 certaines commandes générées par nos soins plutôt que de tenter d'assainir les
    329 commandes entrées par l'utilisateur·ice. En attendant le service étant utilisé
    330 par très peu de personnes et la survie du serveur n'étant pas absolument
    331 primordiale[^9] j'ai décidé que c'était suffisant. Je vais soumettre l'exercice
    332 à des personnes motivées pour tenter de trouver des failles.
    333 
    334 Finalement on pourra y ajouter des logs à coup de `tee` :
    335 
    336     $ cat /tmp/f |
    337         stdbuf -o0 tee prefilter.log |
    338         stdbuf -o0 tr -d '$`&(;|<>' |
    339         stdbuf -o0 grep -E '^conjuguer' |
    340         stdbuf -o0 tee postfilter.log |
    341         stdbuf -o0 sh |
    342         nc -l 127.0.0.1 1234& > /tmp/f
    343 
    344 On peut ajouter des commandes disponibles en les installant sur la machine et en
    345 ajoutant des alternatives à la regex du grep : `^(conjuguer|synonyme)`. On peut
    346 également maintenir un fichier des commandes autorisées, une commande par ligne,
    347 et faire :
    348 
    349         stdbuf -o0 grep -wf authorized
    350 
    351 ## Quelques commentaires, bonus et perspectives pour rendre ça un peu sympa
    352 
    353 ### socat
    354 
    355 Dans les faits et pour plusieurs raisons que j'ai déjà oublié j'utilise côté
    356 serveur `socat`. Les commandes vues précédemment sont les mêmes, à la suite d'un
    357 `cat`, mais existent dans un script séparé qui est renseigné dans la commande
    358 socat qui lance le serveur :
    359 
    360     socat -d -d -lf /var/log/socatlog tcp-listen:2222,fork exec:script
    361 
    362 TODO : éclaircir pourquoi j'ai finalement choisi socat.
    363 En tout cas cet outil score probablement un peu moins bien dans les critères vus
    364 [ici](/services-sobres/#quelle-forme-pour-ces-services-) (32k lignes par ex)
    365 mais est plus polyvalent.
    366 
    367 ### Une commande help
    368 
    369 Une commande `help` est une bonne idée ne serait-ce que pour lister les
    370 commandes dispos. Pour qu'elle s'affiche au lancement d'une session on peut
    371 ajouter un
    372 
    373     echo "help pour la liste des commandes"
    374 
    375 au début du script. Cela à pour inconvénient d'ajouter cette ligne dans les
    376 résultats de commandes lancées non interactivement. Exemple :
    377 
    378     $ nc bebou.netlib.re 2222
    379     help pour la liste des commandes
    380     help
    381     h[elp]
    382 
    383         cette aide
    384 
    385     s[ynonyme] mot
    386 
    387         la liste des synonymes de "mot"
    388     [...]
    389     s table
    390     tableau    14
    391     répertoire 14
    392     pupitre    13
    393     liste      11
    394     catalogue  11
    395     [...]
    396 
    397 mais si l'on passe la commande directement dans stdin (`-N` dira à nc d'envoyer
    398 un caractère de fin de fichier à la fin afin de terminer la connexion et
    399 récupérer la main) :
    400 
    401     $ echo "s table" | nc -N bebou.netlib.re 2222
    402     help ou h pour obtenir de l'aide
    403     tableau	14
    404     répertoire	14
    405     pupitre	13
    406     liste	11
    407     catalogue	11
    408     [...]
    409     $
    410 
    411 On voit que l'on se traine l'aide. Il y a peut-être un moyen d'y remédier côté
    412 serveur mais en attendant je script mes usages non interactifs de façon à
    413 supprimer la première ligne de résultat. Par exemple, le script zsh que
    414 j'utilise pour la conjugaison (noter le `sed '1d'` qui supprime la première
    415 ligne) :
    416 
    417     read ?"Verbe (et filtres) : " verbe
    418     echo "conjuguer -c $verbe" | nc -N bebou.netlib.re 2222 | sed '1d'
    419     read -k1
    420 
    421 ### Des scripts pour un peu plus d'interactivité
    422 
    423 En jouant avec le service de synonyme je me suis rendu compte qu'il était assez
    424 naturel de vouloir sélectionner l'un des synonymes proposer pour voir ses
    425 synonymes et ainsi de suite, à la manière de la navigation dans un document avec
    426 des liens hypertexte. Il aurait été dommage de perdre totalement cette
    427 fonctionnalité là. Pour cela j'ai opté de ne pas complexifier la commande côté
    428 serveur mais de l'implémenter côté client :
    429 
    430 	read ?"Mot : " mot
    431 	while [ -n "$mot" ]
    432 	do
    433 		oldmot=$mot
    434 		echo $oldmot | cut -f1
    435 		mot=$(echo "synonyme $mot" | nc -N bebou.netlib.re 2222 | sed '1d' | fzy)
    436 	done
    437 	read -k1
    438 
    439 Ce script donne ce genre de session de navigation :
    440 
    441     Mot : table
    442     table
    443     >
    444       tableau	14
    445       répertoire	14
    446     > pupitre	13
    447       liste	11
    448 
    449 Puis après sélection de pupitre :
    450 
    451     Mot : table
    452     table
    453     pupitre
    454     >
    455     > lutrin	50
    456       console	20
    457       chaire	20
    458       table	13
    459       bureau	4
    460 
    461 Une fois la navigation terminée on peut en sortir en appuyant sur "echap".
    462 Pour les personnes initié·es voici mon menu [zenu](/zenu/) correspondant :
    463 
    464     _conjuger
    465     _synonyme
    466     ## pre
    467     ## react
    468     ;; (c)
    469         read ?"Verbe (et filtres) : " verbe
    470         echo "conjuguer -c $verbe" | nc -N bebou.netlib.re 2222 | sed '1d'
    471         read -k1
    472     ;; (s)
    473         read ?"Mot : " mot
    474         while [ -n "$mot" ]
    475         do
    476             oldmot=$mot
    477             echo $oldmot | cut -f1
    478             mot=$(echo "synonyme $mot" | nc -N bebou.netlib.re 2222 | sed '1d' | fzy)
    479         done
    480         read -k1
    481 
    482 ### Favoriser le local
    483 
    484 Malgré l'existence de ces services que je compte bien continuer à maintenir je
    485 maintiens ma volonté que les personnes autour de moi les installent en local.
    486 Pour favoriser cela je devrais :
    487 
    488   * En faire des paquets debian
    489   * Mieux les documenter (c'est un peu le foutoir là)
    490   * Publier des menus zenu directement dans les dépôts git et/ou dans les
    491     paquets debian
    492   * Intégrer quelque chose au service qui permette à minima de visibiliser que
    493     c'est possible ?
    494 
    495 [^1]: sur debian faire `sudo apt install netcat-openbsd` si vous ne l'avez pas déjà. En réalité tout outil permettant de se connecter à un port sur une machine distante. `socat` fonctionne, `telnet` aussi etc.
    496 [^2]: article plus très à jour par rapport à ce que je fais aujourd'hui mais passons
    497 [^3]: surtout quand on parle de sobriété dans le numérique, lol.
    498 [^4]: en écrivant ces lignes je me rends compte qu'ils n'ont rien d'évident. Notamment celle-ci. L'intuition première est que peu de personne = projet simple et facile à maintenir, pleins de personnes = projet complexe et difficile à maintenir. Je pense que cette intuition n'est pas totalement fausse mais il faut envisager d'autres paramètres. Une personne peut, si elle est très productive, construire des logiciels qui ne sont raisonnablement maintenu par la suite que par une équipe de personne (eg Fabrice Bellard avec qemu et ffmpeg). Il est également possible qu'un outil soit créé et maintenu par une seule personne sans être pour autant documenté ou partagée. A moins que cet outil soit très simple sa maintenance posera problème. D'une certaine manière l'existence d'une équipe, et donc de plus de monde, autour d'un outil peut offrir de la résilience en cas de perte d'une personne. Ça n'est probablement qu'en combinant les variables du nombre de personnes actives pour maintenir l'outil, le nombre de personnes connaissant bien son fonctionnement et la documentation associée que l'on parviendrait à dégager un avis pertinent sur le rapport entre personnes impliquées et soutenabilité. Il faudrait également y inclure des variables économiques telles que la pérennité des financements du projet s'ils existent, la popularité des technologies utilisées etc. Bref c'est bien plus compliqué que ce que ces cinq critères de base laissent penser.
    499 [^5]: un jour peut-être
    500 [^6]: oui oui, si vous avez l'habitude des manuels des outils GNU ça paraît fou.
    501 [^7]: je dois avouer que je n'étais pas très bon élève lors de mes études mais je n'ai pas souvenir que l'on m'ait enseigné des protocoles aussi fondamentaux qu'HTTP et SMTP en me faisant expérimenter de la sorte. Tout conservait une aura un peu mystérieuse. On m'a pourtant enseigné TCP dans les détails.
    502 [^8]: évidemment la regex ne couvre pas tous les cas, c'est un exemple
    503 [^9]: il ne serait pas très long de le réinstaller tel quel d'autant plus que tout est backupé