<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Le Carnet Technique de Michaël</title><link>https://michael.parienti.net/</link><description>Blog technique de Michaël Parienti</description><atom:link href="https://michael.parienti.net/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>fr</language><copyright>Contents © 2026 &lt;a href="mailto:mon-prenom@parienti.net"&gt;Michaël Parienti&lt;/a&gt; </copyright><lastBuildDate>Mon, 08 Jun 2026 03:38:14 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Un pour les unir tous</title><link>https://michael.parienti.net/posts/2025/05/11/un-pour-les-unir-tous/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Avant c’était pas si mieux&lt;/h2&gt;
  &lt;p&gt;Combien de fois en voulant installer un logiciel quelconque sur une machine debian, je suis tomber sur une
  instruction du genre: &lt;code&gt;curl https://www.closeyoureye.org/random_script.sh | bash&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;&lt;a href="https://michael.parienti.net/public/images/puit.jpeg" alt="Margelle de puit dans la cour d’un monastère." title="Cliquer pour voir l’image en plus grand" style="width: 320px height: 240px"&gt;&lt;img src="https://michael.parienti.net/public/images/puit_m.jpeg" alt="Margelle de puit dans la cour d’un monastère." title="Cliquer pour voir l’image en plus grand" style="width: 320px height: 240px"&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;La seule attitude décente face à une telle ligne de commande est de:&lt;/p&gt;
  &lt;ol class="org-ol"&gt;
    &lt;li&gt;lever les yeux au ciel;&lt;/li&gt;
    &lt;li&gt;télécharger le script random dont l’url est fournie;&lt;/li&gt;
    &lt;li&gt;ouvrir le script téléchargé avec son éditeur préféré;&lt;/li&gt;
    &lt;li&gt;extraire les instructions qui concernent notre distribution;&lt;/li&gt;
    &lt;li&gt;les exécuter manuellement, ou depuis un nouveau script.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h2&gt;La découverte&lt;/h2&gt;
  &lt;p&gt;Et puis un jour, en voulant installer une &lt;a href="https://librewolf.net/#what-is-librewolf"&gt;alternative&lt;/a&gt; à
  Firefox, je tombe sur autre chose. Cette fois-ci les instructions sont:&lt;/p&gt;
  &lt;pre class="src src-bash"&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install extrepo -y
sudo extrepo enable librewolf
sudo apt update &amp;amp;&amp;amp; sudo apt install librewolf -y
&lt;/pre&gt;
  &lt;p&gt;Comme son nom l’indique, &lt;a href="https://packages.debian.org/bookworm/extrepo"&gt;extrepo&lt;/a&gt; est un paquet debian qui
  permet d’ajouter facilement des dépôts extérieurs. Les dépôts pris en charge par cet outil sont gérés dans un &lt;a href="https://salsa.debian.org/extrepo-team/extrepo-data"&gt;répertoire git&lt;/a&gt; dédié. On peut y voir la &lt;a href="https://salsa.debian.org/extrepo-team/extrepo-data/-/tree/master/repos/debian?ref_type=heads"&gt;liste des logiciels&lt;/a&gt;
  rendus ainsi disponibles. En voici un petit extrait appétissant:&lt;/p&gt;
  &lt;ul class="org-ul"&gt;
    &lt;li&gt;Crowdsec&lt;/li&gt;
    &lt;li&gt;Docker&lt;/li&gt;
    &lt;li&gt;Fai&lt;/li&gt;
    &lt;li&gt;HAProxy&lt;/li&gt;
    &lt;li&gt;Kubernetes&lt;/li&gt;
    &lt;li&gt;Nodejs&lt;/li&gt;
    &lt;li&gt;Postgresql&lt;/li&gt;
    &lt;li&gt;Signal&lt;/li&gt;
    &lt;li&gt;Wine HQ&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Avant de commencer il vous faudra peut-être jouer avec la configuration du logiciel dans
  &lt;code&gt;/etc/extrepo/config.yaml&lt;/code&gt; pour viser la bonne version de debian et éventuellement ajouter les dépôts
  &lt;code&gt;contrib&lt;/code&gt; ou &lt;code&gt;non-free&lt;/code&gt;. Vous pourrez aussi installer &lt;code&gt;extrepo-offline-data&lt;/code&gt; pour
  éviter des requêtes web à chaque utilisation de l’outil.&lt;/p&gt;
  &lt;p&gt;Les deux commandes principales à connaître sont &lt;code&gt;extrepo search&lt;/code&gt; et &lt;code&gt;extrepo enable&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;En guise de conclusion j’espère juste que le répertoire git contenant la liste des dépôts et leurs clefs publiques
  est surveillé comme du petit lait sur le feu par les équipes debian. La sécurité de bien des serveurs en ligne est
  dépend.&lt;/p&gt;</description><category>Debian</category><guid>https://michael.parienti.net/posts/2025/05/11/un-pour-les-unir-tous/</guid><pubDate>Sun, 11 May 2025 09:57:02 GMT</pubDate></item><item><title>Récupération d’information rapide</title><link>https://michael.parienti.net/posts/2025/04/06/recuperation-d-informations/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Nouveaux serveurs à gérer&lt;/h2&gt;
  &lt;p&gt;Je viens de récupérer plusieurs machines à gérer. Je n’ai qu’un accès ssh à chaque machine, et une description
  sommaire de son rôle. Hors j’aimerais savoir rapidement de quoi est capable chaque serveur:&lt;/p&gt;
  &lt;ul class="org-ul"&gt;
    &lt;li&gt;combien a-t-il de RAM?&lt;/li&gt;
    &lt;li&gt;les partitions,&lt;/li&gt;
    &lt;li&gt;l’espace disponible sur les disques,&lt;/li&gt;
    &lt;li&gt;le nombre de processeurs,&lt;/li&gt;
    &lt;li&gt;etc.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;&lt;a href="https://michael.parienti.net/public/images/tour.jpeg" alt="Tour avec un balcon sur un ciel bleu." title="Cliquer pour voir l’image en plus grand" style="width: 320px height: 439px"&gt;&lt;img src="https://michael.parienti.net/public/images/tour_m.jpeg" alt="Tour avec un balcon sur un ciel bleu." title="Cliquer pour voir l’image en plus grand" style="width: 320px height: 439px"&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;h2&gt;L’outil&lt;/h2&gt;
  &lt;p&gt;Après quelques recherches je suis tombé sur l’outil magique qui fait tout ça: &lt;a href="https://smxi.org/docs/inxi.htm"&gt;inxi&lt;/a&gt;. Écris en perl, inxi va récupérer toutes les informations dans l’arborescence
  &lt;code&gt;/proc/&lt;/code&gt; et &lt;code&gt;/dev/&lt;/code&gt; pour nous présenter une synthèse lisible par nous, pauvres humains.&lt;/p&gt;
  &lt;p&gt;Pour mes serveurs, je l’utilise avec les options &lt;code&gt;-C -D -j -m -p -S -n -o -R&lt;/code&gt;&lt;/p&gt;
  &lt;pre class="src src-bash"&gt;inxi -C -D -j -m -p -S -n -o -R
&lt;/pre&gt;
  &lt;p&gt;Mais il existe d’autres &lt;a href="https://smxi.org/docs/inxi-options.htm"&gt;options&lt;/a&gt; pour afficher à peu près tout:
  les besoins ne sont pas les même pour un desktop et pour un serveur.&lt;/p&gt;
  &lt;p&gt;L’avantage qu’il soit écrit en perl, c’est qu’on peut simplement copier l’exécutable sur un serveur et le lancer
  ensuite directement, sans avoir à installer tout le paquet.&lt;/p&gt;</description><guid>https://michael.parienti.net/posts/2025/04/06/recuperation-d-informations/</guid><pubDate>Sun, 06 Apr 2025 13:25:56 GMT</pubDate></item><item><title>Un tunnel low cost</title><link>https://michael.parienti.net/posts/2025/03/09/tunnel-low-cost/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Besoin de tunnel&lt;/h2&gt;
  &lt;p&gt;La dernière mode chez les développeurs, c’est d’exposer publiquement son environnement local, généralement une
  application web en cours d’écriture. De mon côté, il m’a été demandé de travailler sur un système de paiement dont la
  configuration nécessitait que ma machine de développement soit accessible au service de paiement.&lt;/p&gt;
  &lt;p&gt;&lt;a href="https://michael.parienti.net/public/images/detail_maison.jpeg" alt="Détail d’une maison alsacienne. Cliquer pour voir l’image en plus grand" title="Détail d’une maison alsacienne"&gt;&lt;img src="https://michael.parienti.net/public/images/detail_maison_m.jpeg" alt="Détail d’une maison alsacienne. Cliquer pour voir l’image en plus grand" title="Détail d’une maison alsacienne" style="width: 360px; height: 163px"&gt;&lt;/a&gt;&lt;/p&gt;
  &lt;p&gt;Il m’a été proposé d’utiliser les &lt;a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/"&gt;tunnels Cloudflare&lt;/a&gt;, ou bien d’installer
  &lt;a href="https://github.com/inconshreveable/ngrok"&gt;ngrok&lt;/a&gt;. Mais ces deux solutions, ainsi que leurs &lt;a href="https://github.com/anderspitman/awesome-tunneling"&gt;multiples alternatives&lt;/a&gt;, me semblaient «/overkill/» pour mon
  simple besoin. J’ai donc préféré m’amuser à implémenter une solution plus modeste et sur mesure, que je vais présenter
  ci-après.&lt;/p&gt;
  &lt;h2&gt;Solution maison&lt;/h2&gt;
  &lt;p&gt;Je contrôle déjà un serveur web qui est accessible publiquement sur internet. C’est le serveur web qui héberge le
  blog sur lequel vous êtes certainement en train de lire cet article. Mon objectif va être d’utiliser ce serveur comme
  proxy web sur un nom de domaine dédié, qui transmettra toutes les requêtes vers mon serveur de développement, qui lui
  tournera sur mon portable dans des containers configurés avec &lt;code&gt;docker-compose&lt;/code&gt;.&lt;/p&gt;
  &lt;h3&gt;Configuration DNS&lt;/h3&gt;
  &lt;p&gt;La première étape consiste donc à faire pointer le nom de domaine sous lequel on veut rendre accessible notre
  environnement de développement vers ce serveur.&lt;/p&gt;
  &lt;p&gt;Par convention je vais utiliser les noms suivants:&lt;/p&gt;
  &lt;ul class="org-ul"&gt;
    &lt;li&gt;&lt;code&gt;my-web-server.net&lt;/code&gt;: le nom de domaine de mon serveur web public;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;dev1.devs.my-web-server.net&lt;/code&gt;: le nom de domaine sous lequel l’environnement de développement sera
    accessible.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;L’enregistrement DNS à créer ressemblera à quelque chose comme: &lt;code&gt;*.devs.my-web-server.net CNAME
  my-web-server.net&lt;/code&gt;&lt;/p&gt;
  &lt;h3&gt;Configuration Caddy&lt;/h3&gt;
  &lt;p&gt;Mon serveur web utilise &lt;a href="https://caddyserver.com/"&gt;Caddy&lt;/a&gt;. Ici je vais utiliser deux fonctionnalités de
  cet outil particulièrement pratiques:&lt;/p&gt;
  &lt;ol class="org-ol"&gt;
    &lt;li&gt;en déclarant un nom de domaine ouvert sur le port &lt;code&gt;443&lt;/code&gt;, Caddy récupère automatiquement le certificat
    Letsencrypt!&lt;/li&gt;
    &lt;li&gt;Un reverse proxy se configure en une seule ligne.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;La section de ma configuration Caddy dédiée au tunnel ressemble à ceci:&lt;/p&gt;
  &lt;pre class="src src-Caddyfile"&gt;dev1.devs.my-web-server.net:80,
dev1.devs.my-web-server.net:443 {
    log {
        output file /var/log/caddy/dev1-devs.log
    }
    reverse_proxy {
        to 127.0.0.1:8888
   }
}
&lt;/pre&gt;
  &lt;h3&gt;Configuration Docker avec le certificat&lt;/h3&gt;
  &lt;p&gt;Lorsque mon application web sera accessible depuis l’extérieur, Caddy va utiliser le certificat généré par
  Letsencrypt pour sécuriser la connexion. Mais lorsque j’accède à cette même application en local depuis mon portable,
  c’est au serveur web qui tourne dans Docker de s’en occuper. Pour cela ce serveur a aussi besoin des fichiers du
  certificat.&lt;/p&gt;
  &lt;p&gt;Ces fichiers (la clé publique et la clé privée) se trouvent dans le sous répertoire
  &lt;code&gt;dev1.devs.my-web-server.net&lt;/code&gt; du répertoire
  &lt;code&gt;/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/&lt;/code&gt; Il faut les copier
  en local, puis les insérer dans le container qui fera tourner le serveur web.&lt;/p&gt;
  &lt;p&gt;Dans le &lt;code&gt;Dockerfile&lt;/code&gt; du serveur web on trouvera donc quelque chose qui ressemble à:&lt;/p&gt;
  &lt;pre class="src src-Dockerfile"&gt;COPY certs/dev1.devs.my-web-server.net.crt /usr/local/apache2/conf/dev1.devs.my-web-server.net.crt
COPY certs/dev1.devs.my-web-server.net.key /usr/local/apache2/conf/dev1.devs.my-web-server.net.key
&lt;/pre&gt;
  &lt;p&gt;Dans mon cas particulier l’application en local est servie par un serveur apache. La configuration de ce serveur
  ressemble à ceci:&lt;/p&gt;
  &lt;pre class="src src-conf"&gt;&amp;lt;VirtualHost _default_:443&amp;gt;
    DocumentRoot &lt;span class="org-string"&gt;"/var/www/my-app/"&lt;/span&gt;
    ServerName dev1.devs.my-web-server.net

    SSLEngine on
    &amp;lt;Directory &lt;span class="org-string"&gt;"/var/www/my-app/"&lt;/span&gt;&amp;gt;
        AllowOverride All
        Require all granted
    &amp;lt;/Directory&amp;gt;

    SSLCertificateFile &lt;span class="org-string"&gt;"/usr/local/apache2/conf/dev1.devs.my-web-server.net.crt"&lt;/span&gt;
    SSLCertificateKeyFile &lt;span class="org-string"&gt;"/usr/local/apache2/conf/dev1.devs.my-web-server.net.key"&lt;/span&gt;
    Protocols h2 http/1.1
&amp;lt;/VirtualHost&amp;gt;
&lt;/pre&gt;
  &lt;h3&gt;Modification du fichier /etc/hosts&lt;/h3&gt;
  &lt;p&gt;Pour pouvoir travailler localement, sans passer par le proxy, il faut associer l’adresse IP du container apache au
  nom de domaine &lt;code&gt;dev1.devs.my-web-server.net&lt;/code&gt;. On récupère cette adresse avec la commande suivante:&lt;/p&gt;
  &lt;pre class="src src-bash"&gt;docker inspect &lt;span class="org-sh-escaped-newline"&gt;\&lt;/span&gt;
     --format=&lt;span class="org-string"&gt;'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'&lt;/span&gt; &lt;span class="org-sh-escaped-newline"&gt;\&lt;/span&gt;
    $(&lt;span class="org-sh-quoted-exec"&gt;docker compose ps -q apache&lt;/span&gt;)
&lt;/pre&gt;
  &lt;h3&gt;Connexion ssh&lt;/h3&gt;
  &lt;p&gt;La dernière étape consiste à créer le tunnel, avec SSH, entre notre machine locale et le serveur web:&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;ssh -R 8888:127.0.0.1:8351 my-web-server.net&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Ici on a:&lt;/p&gt;
  &lt;ul class="org-ul"&gt;
    &lt;li&gt;&lt;code&gt;8351&lt;/code&gt; le port ouvert de notre serveur web dans votre docker-compose;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;8888&lt;/code&gt; le port qui est dans la configuration reverse proxy de Caddy.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Et voilà!&lt;/p&gt;
  &lt;h2&gt;Aller plus loin&lt;/h2&gt;
  &lt;p&gt;Il ne semble pas trop difficile de bricoler une solution qui automatise un peu toutes ces étapes. D’ailleurs c’est
  pour cela que j’ai déclaré le domaine &lt;code&gt;*.devs.my-web-server.net&lt;/code&gt; dans ma configuration dns, au lieu de
  &lt;code&gt;dev1.my-web-server.net&lt;/code&gt;. Ainsi je peux ajouter plus facilement d’autres domaines sans modifier mon serveur
  DNS. Je n’aurais ensuite que les modifications de la configuration Caddy et de docker à programmer. Pour le moment, avec
  un seul environnement à rendre accessible, je n‘ai pas besoin d’automatiser plus.&lt;/p&gt;
  &lt;h3&gt;Post Scriptum&lt;/h3&gt;
  &lt;p&gt;Après avoir écrit cet article, je découvre un &lt;a href="https://github.com/anderspitman/SirTunnel"&gt;projet&lt;/a&gt; qui met
  en œuvre exactement le même procédé que moi, avec un début d’automatisation.&lt;/p&gt;</description><category>caddy</category><category>docker</category><category>ssh</category><guid>https://michael.parienti.net/posts/2025/03/09/tunnel-low-cost/</guid><pubDate>Sun, 09 Mar 2025 16:39:10 GMT</pubDate></item><item><title>Nouvel outil de traduction hors ligne </title><link>https://michael.parienti.net/posts/2023/01/31/outil-de-traduction-hors-ligne/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Le besoin&lt;/h2&gt;

&lt;p&gt;
Vivant et travaillant en Allemagne, utilisant les langues anglaise et
allemande de manière professionnelle, le français et l’allemand dans la
sphère privée, je suis un utilisateur pas très modéré des outils de
traduction en ligne.
&lt;/p&gt;


&lt;div class="figure"&gt;
&lt;p&gt;&lt;img src="https://michael.parienti.net/public/images/arc-en-ciel-de-classeurs.jpeg" alt="Des classeurs de toutes les couleurs" title="Multi langue, multi couleurs" style="width: 16em max-width: 360px"&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
Aussi l’&lt;a href="https://blog.mozilla.org/en/mozilla/local-translation-add-on-project-bergamot/"&gt;annonce &lt;/a&gt; d’un outil de traduction hors ligne basé sur des &lt;a href="https://browser.mt/"&gt;travaux
universitaires&lt;/a&gt; par Mozilla m’a enchanté. La &lt;a href="https://hacks.mozilla.org/2022/06/training-efficient-neural-network-models-for-firefox-translations/"&gt;description technique&lt;/a&gt; de la
conception de l’outil est intéressante à lire.
&lt;/p&gt;

&lt;p&gt;
Malheureusement l’outil n’est distribué que sous la forme d’une extension
Firefox, et le dépôt &lt;a href="https://github.com/browsermt/bergamot-translator/"&gt;git&lt;/a&gt; et les explications pour obtenir une application
&lt;a href="https://github.com/browsermt/bergamot-translator/blob/main/examples/run-native.sh"&gt;indépendante&lt;/a&gt; est indigeste.  «&lt;a href="https://github.com/browsermt/bergamot-translator/issues/440"&gt;Hillariously difficult to use&lt;/a&gt;» pour rependre
le titre d’un rapport un bogue, dont une réponse pointe vers &lt;a href="https://github.com/kroketio/kotki"&gt;Kotki&lt;/a&gt;, un
projet dérivé qui promet de simplifier l’utilisation de l’outil.
&lt;/p&gt;





&lt;h2&gt;L’outil&lt;/h2&gt;

&lt;p&gt;
L’installation de Kotki se déroule en deux partie. Au niveau système, en
tant que root:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;apt install -y cmake ccache build-essential git pkg-config &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
    rapidjson-dev pybind11-dev libyaml-cpp-dev python3-dev &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
    python3-virtualenv libopenblas-dev libpcre2-dev &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
    libprotobuf-dev protobuf-compiler libsqlite3-dev
pip3 install kotki -v
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
En tant qu’utilisateur, il faut ensuite télécharger les «modèles» permettant
de traduire d’une langue à l’autre:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;mkdir -p ~/.config/kotki/models/
&lt;span style="color: #364fc7;"&gt;cd&lt;/span&gt; /tmp/
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;Voir https://github.com/kroketio/kotki/releases&lt;/span&gt;
wget https://github.com/kroketio/kotki/releases/download/0.6.0/kotki_models_0.3.3-tiny.zip
unzip kotki_models_0.3.3-tiny.zip -d ~/.config/kotki/models
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Personnellement je télécharge la version &lt;code&gt;tiny&lt;/code&gt; du fichier, parce que le
fichier contient les modèles de traduction dont j’ai besoin. Si vous êtes
intéressé par le russe ou l’ukrainien, la version complète sera nécessaire:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;wget https://github.com/kroketio/kotki/releases/download/0.6.0/kotki_models_0.3.3-tiny.zip
unzip kotki_models_0.3.3.zip -d ~/.config/kotki/models
&lt;/pre&gt;
&lt;/div&gt;





&lt;h2&gt;Utilisation&lt;/h2&gt;

&lt;p&gt;
Ça marche plutôt pas mal:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;kotki-cli -i &lt;span style="color: #862e9c;"&gt;"Longtemps je me suis couché de bonne heure."&lt;/span&gt;
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;For a long time I went to bed early.&lt;/span&gt;

kotki-cli -m enfr -i &lt;span style="color: #862e9c;"&gt;"For a long time I went to bed early."&lt;/span&gt;
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;Pendant longtemps, je suis allé me coucher tôt.&lt;/span&gt;

kotki-cli  -i &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
&lt;span style="color: #862e9c;"&gt;"Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte, \&lt;/span&gt;
&lt;span style="color: #862e9c;"&gt;fand er sich in seinem Bett zu einem ungeheueren Ungeziefer \&lt;/span&gt;
&lt;span style="color: #862e9c;"&gt;verwandelt."&lt;/span&gt;
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;One morning, when Gregor Samsa awoke from troubled dreams,&lt;/span&gt;
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;he found himself in his bed turning into a monstrous vermin.&lt;/span&gt;

kotki-cli -m ende -i &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
&lt;span style="color: #862e9c;"&gt;"One morning, when Gregor Samsa awoke from troubled dreams,\&lt;/span&gt;
&lt;span style="color: #862e9c;"&gt; he found himself in his bed turning into a monstrous vermin."&lt;/span&gt;
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;Eines Morgens, als Gregor Samsa aus unruhigen Träumen erwachte,&lt;/span&gt;
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;fand er sich in seinem Bett wieder, das sich in ein&lt;/span&gt;
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;ungesäuertes Ungeziefer verwandelte.&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Mais l’allemand, n’est pas encore très au point.
&lt;/p&gt;

&lt;p&gt;
Une autre critique:
l’anglais est pivot.
Il n’existe pas (encore?) de modèle permettant
de traduire de l’allemand vers le français
ou du français vers l’allemand.
&lt;/p&gt;</description><category>Offline</category><guid>https://michael.parienti.net/posts/2023/01/31/outil-de-traduction-hors-ligne/</guid><pubDate>Tue, 31 Jan 2023 19:11:00 GMT</pubDate></item><item><title>Utiliser l’historique Bash</title><link>https://michael.parienti.net/posts/2021/08/31/utiliser-l-historique-bash/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Apperçu rapide&lt;/h2&gt;

&lt;p&gt;
Bash propose des raccourcis bien utiles pour relancer des commandes, ou des
bouts de commandes, précédemment exécutées. Cette page va recenser ceux que
j’ai trouvés les plus utiles jusqu’à présent.
&lt;/p&gt;



&lt;div class="figure"&gt;
&lt;p&gt;&lt;a href="https://michael.parienti.net/public/images/passe-et-present.jpeg" alt="Quand le présent rejoint le passé, allégorie. Cliquer pour voir l’image en plus grand" title="Quand le présent rejoint le passé, allégorie" style="width: 320px height: 252px"&gt;&lt;img src="https://michael.parienti.net/public/images/passe-et-present_m.jpeg" alt="Quand le présent rejoint le passé, allégorie. Cliquer pour voir l’image en plus grand" title="Quand le présent rejoint le passé, allégorie" style="width: 320px height: 252px"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;
Voici quelques exemples d’usage:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;Relance la dernière commande en la faisant précéder par sudo&lt;/span&gt;
sudo !!
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;Opération inverse: relancer la dernière commande sudo sans sudo&lt;/span&gt;
!*
&lt;span style="color: #495057; font-style: italic;"&gt;# &lt;/span&gt;&lt;span style="color: #495057; font-style: italic;"&gt;Pour modifier le dernier fichier visualisé avec less&lt;/span&gt;
!less:s/less/vi/
&lt;/pre&gt;
&lt;/div&gt;





&lt;h2&gt;Tableau récapitulatif&lt;/h2&gt;

&lt;p&gt;
Et voici un tableau à garder sous la main en cas de besoin
&lt;/p&gt;
&lt;table&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;!!&lt;/td&gt;
&lt;td class="org-left"&gt;dernière commande&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!rm&lt;/td&gt;
&lt;td class="org-left"&gt;dernière commande qui commence par &lt;code&gt;rm&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!?force?&lt;/td&gt;
&lt;td class="org-left"&gt;dernière commande qui contient &lt;code&gt;force&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!$&lt;/td&gt;
&lt;td class="org-left"&gt;dernier argument de la dernière commande executée&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!^&lt;/td&gt;
&lt;td class="org-left"&gt;premier argument de la dernière commande executée&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!*&lt;/td&gt;
&lt;td class="org-left"&gt;tous les arguments de la dernière commande executée (synonymes: &lt;code&gt;!!:1*&lt;/code&gt; &lt;code&gt;!!:1-$&lt;/code&gt; &lt;code&gt;!!:*&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!scp$&lt;/td&gt;
&lt;td class="org-left"&gt;dernier argument de la dernière commande qui commence par &lt;code&gt;scp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!scp^&lt;/td&gt;
&lt;td class="org-left"&gt;premier argument de la dernière commence qui  commence par &lt;code&gt;scp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;:p&lt;/td&gt;
&lt;td class="org-left"&gt;affichage au lieu d’exécuter&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;:h&lt;/td&gt;
&lt;td class="org-left"&gt;dirname (&lt;i&gt;head&lt;/i&gt;)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;:t&lt;/td&gt;
&lt;td class="org-left"&gt;filename (&lt;i&gt;tail&lt;/i&gt;)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;:r&lt;/td&gt;
&lt;td class="org-left"&gt;enlève l’extension (peut être utilisé deux fois pour des fichiers &lt;code&gt;tar.gz&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;:e&lt;/td&gt;
&lt;td class="org-left"&gt;retourne l’extension seulement&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;^search^replace&lt;/td&gt;
&lt;td class="org-left"&gt;remplace &lt;code&gt;search&lt;/code&gt; par &lt;code&gt;replace&lt;/code&gt;  dans la dernière commande&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!rm:s/search/replace/&lt;/td&gt;
&lt;td class="org-left"&gt;remplace &lt;code&gt;search&lt;/code&gt;  par &lt;code&gt;replace&lt;/code&gt;  dans la dernière commande commençant par &lt;code&gt;rm&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!rm:sg/search/replace/&lt;/td&gt;
&lt;td class="org-left"&gt;remplace partout …&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;sudo !!&lt;/td&gt;
&lt;td class="org-left"&gt;relance la commande précédente avec &lt;code&gt;sudo&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;chmod +x !$&lt;/td&gt;
&lt;td class="org-left"&gt;un exemple parmi mille de l’utilisation du racourci &lt;code&gt;!$&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!scp^:h&lt;/td&gt;
&lt;td class="org-left"&gt;le chemin du fichier copié par &lt;code&gt;scp&lt;/code&gt; (si le fichier était le premier argument à &lt;code&gt;scp&lt;/code&gt; ie il n’y avait pas d’options)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;!grunt:2-$:p&lt;/td&gt;
&lt;td class="org-left"&gt;affichage tous les arguments sauf le premier de la dernière commande commençant par &lt;code&gt;grunt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description><category>bash</category><guid>https://michael.parienti.net/posts/2021/08/31/utiliser-l-historique-bash/</guid><pubDate>Tue, 31 Aug 2021 16:35:00 GMT</pubDate></item><item><title>Re-écrire un historique git</title><link>https://michael.parienti.net/posts/2021/06/09/re-ecrire-l-historique-git/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Contexte&lt;/h2&gt;

&lt;p&gt;
Ça y est. Après des mois de travail appliqué, le projet est achevé: toutes les fonctionalités ont été implementées, la couverture de tests est satisfaisante, les scripts de déploiement vers les différents environnements fonctionnent.
&lt;/p&gt;

&lt;p&gt;
Bref le client est satisfait et l’heure est venue de transmettre le projet. Cet fois-ci le client souhaite être autonome et continuer seul à exploiter et faire évoluer le logiciel. C’est son choix, c’est son droit, pas de problème.
&lt;/p&gt;

&lt;p&gt;
Une dernière vérification sur le dépôt dévoile une petit souci: le script de déploiement, lors de la phase de construction du paquet, utilise un fichier &lt;code&gt;auth.json&lt;/code&gt; utilisé par composer afin d’accéder à des composants php sous licence. Et ce fichier est enregistré dans le dépôt. Donc si le projet est livré en l’état au client, celui-ci continuera à avoir accès aux dépôts privés.
&lt;/p&gt;


&lt;div class="figure"&gt;
&lt;p&gt;&lt;a href="https://michael.parienti.net/public/images/porte-ouverte.jpeg" alt="Porte ouverte sur un espace délabré. Cliquer pour voir l’image en plus grand" title="Porte ouverte sur un espace délabré" style="width: 320px height: 361px"&gt;&lt;img src="https://michael.parienti.net/public/images/porte-ouverte_m.jpeg" alt="Porte ouverte sur un espace délabré. Cliquer pour voir l’image en plus grand" title="Porte ouverte sur un espace délabré" style="width: 320px height: 361px"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;





&lt;h2&gt;Le problème&lt;/h2&gt;

&lt;p&gt;
Après consultation du département des ventes, nous apprenons que nous devons distinguer plusieurs cas:
&lt;/p&gt;
&lt;ul class="org-ul"&gt;
&lt;li&gt;il y a des composants pour lesquels le client a acquis les droits sur les mises à jour futures;&lt;/li&gt;
&lt;li&gt;pour d’autres logiciels, seule la version disponible au moment de la livraison devra rester accessible;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Pour les premiers composants, les identifiants peuvent rester dans le fichier &lt;code&gt;auth.json&lt;/code&gt; sans problème. Lorsque les futurs développeurs du projet lanceront la commande &lt;code&gt;composer update&lt;/code&gt; les dernières versions seront alors téléchargées. En revanche pour les autres composants (un seul en fait) il va falloir faire autrement.
&lt;/p&gt;

&lt;p&gt;
La méthode va être la suivante:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;retirer les clefs d’accès au dépôt du composant en question du fichier &lt;code&gt;auth.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;insérer «/en dur/» dans le dépôt git les sources du composant, et mettre à jour les fichiers &lt;code&gt;composer.json&lt;/code&gt; et &lt;code&gt;composer.lock&lt;/code&gt; en conséquent.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Nous allons nous simplifier la tâche: la deuxième partie (copie du composant dans le dépôt) sera mise en œuvre dans un nouveau commit. C’est un peu de la triche parce que cela signifie que le projet livré ne tournera pas ou ne pourra pas être construit avec les commits précédents le dernier. Néanmoins:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;c’est contractuellement Ok;&lt;/li&gt;
&lt;li&gt;cela fera à peine un peu plus de travail pour les nouveaux développeurs lorsqu’ils voudront utiliser un git &lt;a href="https://git-scm.com/docs/git-bisect"&gt;bisect&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Quant à la première partie du nettoyage de notre dépôt git, nous allons devoir utiliser un outil diabolique: git &lt;a href="https://git-scm.com/docs/git-filter-branch"&gt;filter-branch&lt;/a&gt;.
&lt;/p&gt;




&lt;h2&gt;La solution&lt;/h2&gt;

&lt;p&gt;
Cet outil est tellement diabolique que la documentation officielle vous suggère d’utiliser une alternative plus sûre comme &lt;a href="https://github.com/newren/git-filter-repo/"&gt;filter-repo&lt;/a&gt;. Après avoir attentivement lu la documentation des deux outils, j’ai préféré utiliser le plus dangereux des deux, &lt;code&gt;filter-branch&lt;/code&gt;. Pas par amour du risque, mais par besoin de simplicité.
&lt;/p&gt;

&lt;p&gt;
Les deux outils permettent de re-écrire l’historique d’un dépôt git. Modifier l’historique d’un dépôt git n’est pas anodin. Une fois le serveur de référence mis à jour avec le nouvel historique, tous les développeurs devront re-cloner leur dépôt avant de pouvoir pousser à nouveau leurs modifications. Bien sûre, dans le cas décrit ici, cela n’est pas problématique, puisqu’il n’y aura que des nouveaux développeurs.
&lt;/p&gt;

&lt;p&gt;
Alors que &lt;a href="https://htmlpreview.github.io/?https://github.com/newren/git-filter-repo/blob/docs/html/git-filter-repo.html#EXAMPLES"&gt;filter-repo&lt;/a&gt; permet essentiellement de modifier l’historique d’un dépôt git en supprimant, ajoutant ou modifiant des fichiers dans chaque commit, &lt;code&gt;filter-branch&lt;/code&gt; permet d’exécuter une commande avant chaque commit. Dans notre cas, nous allons écraser le fichier &lt;code&gt;auth.json&lt;/code&gt; avec la version contenant les clefs permises.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;git filter-branch --tree-filter &lt;span style="color: #862e9c;"&gt;'cp /tmp/auth.json src/auth.json'&lt;/span&gt; HEAD
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Et voilà!
&lt;/p&gt;

&lt;p&gt;
À noter:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;tous vos commits ont maintenant des identifiants différents;&lt;/li&gt;
&lt;li&gt;le fichier &lt;code&gt;src/auth.json&lt;/code&gt; a été automatiquement ajouté au premier commit, même si cela n’était pas le cas avant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Mon projet comportait quelques centaines de commits. La commande n’a pas mis plus de quelques minutes pour s’exécuter sur un ordinateur type desktop.
&lt;/p&gt;

&lt;p&gt;
Encore une fois, la commande &lt;code&gt;git filter-branch&lt;/code&gt; est à utiliser avec parcimonie, et uniquement en dernier recours.
&lt;/p&gt;</description><category>git</category><guid>https://michael.parienti.net/posts/2021/06/09/re-ecrire-l-historique-git/</guid><pubDate>Wed, 09 Jun 2021 15:53:00 GMT</pubDate></item><item><title>Astuces de printemps</title><link>https://michael.parienti.net/posts/2021/05/21/astuces-de-printemps/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Astuces de printemps / aka nouvelle fournée de Petits Tips&lt;/h2&gt;

&lt;p&gt;
D’après le calendrier c‘est le printemps. Il est temps de publier une
nouvelle liste de petits trucs. Dorénavant j’appellerai ces articles «p'titstips».
&lt;/p&gt;


&lt;div class="figure"&gt;
&lt;p&gt;&lt;a href="https://michael.parienti.net/public/images/fleurs.jpeg" alt="Parterre de fleurs" title="Parterre de fleurs" style="width: 340px height: 220"&gt;&lt;img src="https://michael.parienti.net/public/images/fleurs_m.jpeg" alt="Parterre de fleurs" title="Parterre de fleurs" style="width: 340px height: 220"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;




&lt;h2&gt;Supprimer le canal alpha des images&lt;/h2&gt;

&lt;p&gt;
À cause d’un bug dans une librairie utilisée dans un projet, toutes les
images avec un fond transparent apparaissaient avec un fond noir. En
attendant une version corrigée de la librairie, il a été décidé de mettre un
fond blanc aux images avec transparence. Voici la commande qui réalise cette
transformation:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;convert -resize 200 -background white -alpha remove pic-with-apha.png pic-with-white-bg.png
&lt;/pre&gt;
&lt;/div&gt;





&lt;h2&gt;Docker&lt;/h2&gt;

&lt;p&gt;
Lorsque l’hébergeur de votre site vous a mis à disposition une base de
donnée dans un container, mais que le container n’est pas démarré
automatiquement lorsque le serveur redémarre, il faut changer la
configuration du container comme ci-dessous.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;docker update --restart always mysql-server-container
&lt;/pre&gt;
&lt;/div&gt;





&lt;h2&gt;Redirection de port à l’intérieur d’un container&lt;/h2&gt;

&lt;p&gt;
Imaginons une application web dans un container, dont le port externe au
container 8092 est redirigé vers le port interne 80. Notre application est
configurée pour être appelée sur l’adresse 127.0.0.1:8092. Mais lorsque
l’application s’appelle elle-même depuis l’intérieur du container, le port
8092 n’est pas atteignable. Il faut donc créer une redirection en utilisant
&lt;code&gt;socat&lt;/code&gt; par exemple:
&lt;/p&gt;

&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;socat tcp-l:8092,fork,reuseaddr tcp:127.0.0.1:80
&lt;/pre&gt;
&lt;/div&gt;





&lt;h2&gt;Convert mp4 into gif&lt;/h2&gt;

&lt;p&gt;
Comme souvent une image veut mieux qu’un long discours, et en description de
bug, une vidéo vaut mieux qu’une image. &lt;a href="https://github.com/vkohaupt/vokoscreenNG"&gt;Vokoscreen&lt;/a&gt; est donc votre ami pour les
déclarations de bug, cet outil vous permettant d’enregistrer ce que vous
faites à l’écran. Et lorsque vous avez enregistré votre bug mais que le
formulaire du service client pour ouvrir un ticket n’accepte que le format
&lt;code&gt;gif&lt;/code&gt;, alors &lt;code&gt;ffmpeg&lt;/code&gt; vient à la rescousse.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;ffmpeg &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
  -i vokoscreenNG-2021-04-18_12-25-57.mp4 &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
  -r 15 &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
  -vf &lt;span style="color: #862e9c;"&gt;"split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse"&lt;/span&gt; &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
  bug-live-test-credit-card.gif
&lt;/pre&gt;
&lt;/div&gt;




&lt;h2&gt;Background dynamique&lt;/h2&gt;

&lt;p&gt;
Vous n’arrivez pas à choisir votre fond d’écran? Ne choisissez pas, et changer
le fond d’écran toutes les cinq minutes.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;&lt;span style="color: #364fc7; font-weight: bold;"&gt;while&lt;/span&gt; true ; &lt;span style="color: #364fc7; font-weight: bold;"&gt;do  for&lt;/span&gt; f&lt;span style="color: #364fc7; font-weight: bold;"&gt; in&lt;/span&gt; &lt;span style="color: #0b7285;"&gt;`ls *|sort -R`&lt;/span&gt; ; &lt;span style="color: #364fc7; font-weight: bold;"&gt;do&lt;/span&gt; feh --bg-max $&lt;span style="color: #9c36b5;"&gt;f&lt;/span&gt; ; sleep 300  ; &lt;span style="color: #364fc7; font-weight: bold;"&gt;done&lt;/span&gt;; &lt;span style="color: #364fc7; font-weight: bold;"&gt;done&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
(n’a pas été testé avec autre chose qu’&lt;a href="https://awesomewm.org/"&gt;Awesome&lt;/a&gt;)
&lt;/p&gt;</description><category>docker</category><category>ffmpeg</category><category>ligne de commande</category><category>p'tits tips</category><guid>https://michael.parienti.net/posts/2021/05/21/astuces-de-printemps/</guid><pubDate>Fri, 21 May 2021 05:05:00 GMT</pubDate></item><item><title>Tableau récapitulatif des bandes passantes</title><link>https://michael.parienti.net/posts/2021/04/15/tableau-recapitulatif-des-bandes-passantes/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Contexte&lt;/h2&gt;

&lt;p&gt;
Je suis en train de migrer progressivement toutes les mes mini-machines de
mon réseau local de Raspberry 2 et 3 vers le Raspberry 4. J’utilise ces
machines comme:
&lt;/p&gt;
&lt;ul class="org-ul"&gt;
&lt;li&gt;Firewall&lt;/li&gt;
&lt;li&gt;NAS&lt;/li&gt;
&lt;li&gt;Pihole&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Le passage de l’USB 2 des anciennes versions à l’USB 3 de la version du
Raspberry 4, m’a poussé à chercher le &lt;a href="https://fr.wikipedia.org/wiki/Goulot_d%27%C3%A9tranglement_(informatique)"&gt;bottelneck&lt;/a&gt; de mon infrastructure.
&lt;/p&gt;


&lt;div class="figure"&gt;
&lt;p&gt;&lt;a href="https://commons.wikimedia.org/wiki/File:USB_Ethernet_adapter_E220742-1048.jpg" alt="Usb ou ethernet? À la recherche du goulot d'étranglement. Cliquer pour voir l’image en plus grand sur le site de Wikimedia Commons, license CC BY-SA 3.0" title="Usb ou ethernet? À la recherche du goulot d'étranglement" style="width: 320px height: 206px"&gt;&lt;img src="https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/USB_Ethernet_adapter_E220742-1048.jpg/320px-USB_Ethernet_adapter_E220742-1048.jpg" alt="Usb ou ethernet? À la recherche du goulot d'étranglement. Cliquer pour voir l’image en plus grand sur le site de Wikimedia Commons, license CC BY-SA 3.0" title="Usb ou ethernet? À la recherche du goulot d'étranglement" style="width: 320px height: 206px"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;





&lt;h2&gt;Le tableau magique&lt;/h2&gt;

&lt;p&gt;
D’une &lt;a href="https://en.wikipedia.org/wiki/List_of_interface_bit_rates"&gt;page&lt;/a&gt; wikipedia, j’ai extrait les valeurs suivantes:
&lt;/p&gt;
&lt;table&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col" class="org-left"&gt;Connection&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;bit/s&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;MB/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;Fast Ethernet (100BASE-X)&lt;/td&gt;
&lt;td class="org-left"&gt;100 Mbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;12.5 MB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;Gigabit Ethernet (1000BASE-X)&lt;/td&gt;
&lt;td class="org-left"&gt;1 Gbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;125 MB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;2.5 Gigabit Ethernet (2.5GBASE-T)&lt;/td&gt;
&lt;td class="org-left"&gt;2.5 Gbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;312.5 MB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;5 Gigabit Ethernet (5GBASE-T)&lt;/td&gt;
&lt;td class="org-left"&gt;5 Gbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;625 MB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;10 Gigabit Ethernet (10GBASE-X)&lt;/td&gt;
&lt;td class="org-left"&gt;10 Gbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;1.25 GB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;USB 2.0&lt;/td&gt;
&lt;td class="org-left"&gt;480 Mbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;60 MB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;USB 3.0  (aka USB 3.1 Gen 1)&lt;/td&gt;
&lt;td class="org-left"&gt;5 Gbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;500 MB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;USB 3.1  (aka USB 3.1 Gen 2)&lt;/td&gt;
&lt;td class="org-left"&gt;10 Gbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;1.212 GB/s&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;USB 3.2  (aka USB 3.2 Gen 2×2)&lt;/td&gt;
&lt;td class="org-left"&gt;20 Gbit/s&lt;/td&gt;
&lt;td class="org-left"&gt;2.424 GB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;
&lt;b&gt;Conclusion&lt;/b&gt;: Pour profiter réellement de l’USB 3 du NAS il va falloir investir dans un switch 10 Gigabits.
&lt;/p&gt;</description><category>NAS</category><guid>https://michael.parienti.net/posts/2021/04/15/tableau-recapitulatif-des-bandes-passantes/</guid><pubDate>Thu, 15 Apr 2021 15:05:00 GMT</pubDate></item><item><title>Enregistrer des albums depuis youtube</title><link>https://michael.parienti.net/posts/2021/03/31/enregistrer-des-albums-depuis-yt/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Avant&lt;/h2&gt;

&lt;p&gt;
Je suis assez vieux pour me souvenir de l’époque où l’on devait guetter à la
radio le passage de nos hits préférés pour pouvoir les enregistrer et les
ré-ecouter plus tard à loisir.
&lt;/p&gt;


&lt;div class="figure"&gt;
&lt;p&gt;&lt;a href="https://commons.wikimedia.org/wiki/File:Side_A,_TDK_D-C60_20041220.jpg" alt="Vieille cassette audio. Cliquer pour voir l’image en plus grand, license CC BY-SA 3.0" title="Vieille cassette audio" style="width: 240px height: 151px"&gt;&lt;img src="https://upload.wikimedia.org/wikipedia/commons/3/3e/Side_A%2C_TDK_D-C60_20041220.jpg" alt="Vieille cassette audio. Cliquer pour voir l’image en plus grand, license CC BY-SA 3.0" title="Vieille cassette audio" style="width: 240px height: 151px"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;





&lt;h2&gt;Maintenant&lt;/h2&gt;

&lt;p&gt;
Autres temps, autre mœurs. On trouve maintenant sur YouTube&lt;sup&gt;&lt;a id="fnr.1" class="footref" href="https://michael.parienti.net/posts/2021/03/31/enregistrer-des-albums-depuis-yt/#fn.1"&gt;1&lt;/a&gt;&lt;/sup&gt; des albums
entiers, qui n’attendent que la ligne de commande pour être téléchargé
grâce à &lt;a href="https://ytdl-org.github.io/youtube-dl/"&gt;Youtube-dl&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Voici donc la fameuse ligne de commande:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;youtube-dl -i -x -o &lt;span style="color: #862e9c;"&gt;"%(artist)s - %(album)s - %(playlist_index)02d - %(track)s.%(ext)s"&lt;/span&gt; &lt;span style="color: #862e9c;"&gt;\&lt;/span&gt;
 url-de-la-playlist
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Cela vous permet de récupérer toutes les pistes d’un album mis en ligne sous
forme d‘une playlist. Les constituants des noms des chansons sont alors:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;Le nom de l’artiste&lt;/li&gt;
&lt;li&gt;Le nom de l’album&lt;/li&gt;
&lt;li&gt;L’index de la chanson (ce qui permet de jouer les chansons dans l’ordre)&lt;/li&gt;
&lt;li&gt;Le nom de la chanson&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Parfois le nom de l’artiste n’est pas renseigné, il faut donc le remplacer:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;&lt;span style="color: #364fc7; font-weight: bold;"&gt;for&lt;/span&gt; f&lt;span style="color: #364fc7; font-weight: bold;"&gt; in&lt;/span&gt; NA*  ;&lt;span style="color: #364fc7; font-weight: bold;"&gt;do  &lt;/span&gt;&lt;span style="color: #364fc7;"&gt;eval&lt;/span&gt; mv &lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt;$&lt;span style="color: #9c36b5;"&gt;f&lt;/span&gt;&lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt; &lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt;$&lt;span style="color: #364fc7;"&gt;{&lt;/span&gt;&lt;span style="color: #9c36b5;"&gt;f&lt;/span&gt;/NA/Nom de l’artiste&lt;span style="color: #364fc7;"&gt;}&lt;/span&gt;&lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt; ; &lt;span style="color: #364fc7; font-weight: bold;"&gt;done&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Pour d’autres morceaux, c’est le nom de l’album qui manque et qu’il faut remplacer:
&lt;/p&gt;
&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;&lt;span style="color: #364fc7; font-weight: bold;"&gt;for&lt;/span&gt; f&lt;span style="color: #364fc7; font-weight: bold;"&gt; in&lt;/span&gt; *NA*  ;&lt;span style="color: #364fc7; font-weight: bold;"&gt;do  &lt;/span&gt;&lt;span style="color: #364fc7;"&gt;eval&lt;/span&gt; mv &lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt;$&lt;span style="color: #9c36b5;"&gt;f&lt;/span&gt;&lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt; &lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt;$&lt;span style="color: #364fc7;"&gt;{&lt;/span&gt;&lt;span style="color: #9c36b5;"&gt;f&lt;/span&gt;/NA/Nom de l’album&lt;span style="color: #364fc7;"&gt;}&lt;/span&gt;&lt;span style="color: #862e9c;"&gt;\"&lt;/span&gt; ; &lt;span style="color: #364fc7; font-weight: bold;"&gt;done&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;div id="footnotes"&gt;
&lt;h2 class="footnotes"&gt;Notes de bas de page: &lt;/h2&gt;
&lt;div id="text-footnotes"&gt;

&lt;div class="footdef"&gt;&lt;sup&gt;&lt;a id="fn.1" class="footnum" href="https://michael.parienti.net/posts/2021/03/31/enregistrer-des-albums-depuis-yt/#fnr.1"&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;div class="footpara"&gt;&lt;p class="footpara"&gt;
Hélas, je n’ai pas trouvé l’équivallent sur des instances d’&lt;a href="https://redirect.invidious.io/"&gt;Individious&lt;/a&gt;
&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;/div&gt;</description><category>Musique</category><guid>https://michael.parienti.net/posts/2021/03/31/enregistrer-des-albums-depuis-yt/</guid><pubDate>Wed, 31 Mar 2021 21:57:00 GMT</pubDate></item><item><title>Démarrer une debian ARM 64 sur un Raspberry Pi 4 depuis un disque dur externe</title><link>https://michael.parienti.net/posts/2021/03/16/booter-en-arm64-sur-un-disque-externe-son-raspberrypi4/</link><dc:creator>Michaël Parienti</dc:creator><description>&lt;h2&gt;Objectif&lt;/h2&gt;

&lt;p&gt;
Dans cet article je vais expliquer comment faire démarrer son Raspeberry Pi
4 directement depuis un disque dur externe USB. Et pour être totalement
moderne, nous démarrerons une debian ARM64, au lieu de Raspberry Pi OS qui
est devenu &lt;a href="https://tutox.fr/2021/02/11/raspberry-pi-os-et-le-depot-de-satan/"&gt;persona no grata&lt;/a&gt;.
&lt;/p&gt;


&lt;div class="figure"&gt;
&lt;p&gt;&lt;a href="https://michael.parienti.net/public/images/r4.jpeg" alt="Raspbery Pi 4 dans son armure d’acier, qui le protège du chaud. Cliquer pour voir l’image en plus grand" title="Raspbery Pi 4 dans son armure d’acier, qui le protège du chaud" style="width: 240px height: 179px"&gt;&lt;img src="https://michael.parienti.net/public/images/r4_m.jpeg" alt="Raspbery Pi 4 dans son armure d’acier, qui le protège du chaud. Cliquer pour voir l’image en plus grand" title="Raspbery Pi 4 dans son armure d’acier, qui le protège du chaud" style="width: 240px height: 179px"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;





&lt;h2&gt;Première étape, activer l’option &lt;code&gt;boot on usb&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;
Il faut commencer par se procurer une distribution dédiée au Raspberry,
comme par exemple celle que vous pouvez &lt;a href="https://michael.parienti.net/posts/2020/05/01/construire-ses-propres-images-raspbian/"&gt;construire vous même&lt;/a&gt; avec le projet
&lt;a href="https://github.com/RPi-Distro/pi-gen"&gt;pi-gen&lt;/a&gt;. On ne va pas utiliser cette distribution définitivement, mais
uniquement pour mettre à jour et configurer le Raspberry Pi 4. Il faudra
donc utiliser une carte SD, sur laquelle vous aurez installer cette
distribution, et démarrer une première fois dessus.
&lt;/p&gt;

&lt;p&gt;
La mise à jour du programme de démarrage du stocké dans la &lt;a href="https://fr.wikipedia.org/wiki/Electrically-erasable_programmable_read-only_memory"&gt;ROM&lt;/a&gt; du Raspberry
Pi est parfois nécessaire. En allumant le Raspberry sans carte SD, mais
connecté à un écran, vous devriez lire la version de l’Eeprom. Si la date
est inférieur au &lt;code&gt;Sep 3 2020&lt;/code&gt;, une mise à jour est nécessaire.
&lt;/p&gt;

&lt;p&gt;
Pour mettre à jour la ROM, il vous faut, après avoir démarré avec la
distribution dédiée, installer le paquet &lt;code&gt;rpi-eeprom&lt;/code&gt;, puis lancer
&lt;code&gt;rpi-eeprom-update -a&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Après la mise à jour le deuxième rôle de cette distribution est de
configurer l’Eeprom pour autoriser le démarrage depuis un disque dur
externe. Le programme qui autorise cette configuration est
&lt;code&gt;rpi-eeprom-config --edit&lt;/code&gt; . Il faut changer la directive
&lt;code&gt;BOOT_ORDER&lt;/code&gt;. Plusieurs valeurs sont possibles. Le Raspberry Pi essaie de
démarrer depuis les différentes options données, de droite vers gauche par
priorité décroissante.
&lt;/p&gt;

&lt;p&gt;
J’ai entré &lt;code&gt;0x41&lt;/code&gt; comme valeur pour la directive &lt;code&gt;BOOT_ORDER&lt;/code&gt;. Cela signifie:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;Essaie de démarrer sur la carte SD (valeur &lt;code&gt;1&lt;/code&gt; la plus à droite);&lt;/li&gt;
&lt;li&gt;Si cela ne marche pas, essaie de démarrer sur le disque dur externe (valeur &lt;code&gt;4&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Si j’avais configuré le &lt;code&gt;BOOT_ORDER&lt;/code&gt; à &lt;code&gt;0x242&lt;/code&gt;, le Raspberry Pi aurait
essayé de démarrer, dans l’ordre:
&lt;/p&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;depuis la carte SD;&lt;/li&gt;
&lt;li&gt;depuis un disque dur externe&lt;/li&gt;
&lt;li&gt;depuis le réseau (valeur &lt;code&gt;2&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Maintenant il ne nous reste plus qu’à installer une debian ARM64 sur un
disque dur externe.
&lt;/p&gt;




&lt;h2&gt;Installation de Debian ARM&lt;/h2&gt;

&lt;p&gt;
Il existe un &lt;a href="https://raspi.debian.net/"&gt;mini site web&lt;/a&gt; dédié aux images Raspberry PI construites par
Debian. Les images de la distribution debian ARM64 les plus stables se
trouvent &lt;a href="https://raspi.debian.net/tested-images/"&gt;ici&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
La première chose à faire est de brancher un disque dur externe, de type
USB3 de préférence, supportant l’&lt;a href="https://fr.wikipedia.org/wiki/USB_Attached_SCSI"&gt;uasp&lt;/a&gt; serait encore mieux. Ensuite on copie
l’image sur le disque dur, exactement de la même manière que si c’était une
carte SD.
&lt;/p&gt;

&lt;p&gt;
Voici les instructions que je lance pour télécharger une image &lt;a href="https://www.debian.org/releases/buster/"&gt;buster&lt;/a&gt; et la
copier sur un disque externe. Ces instructions sont valables pour les images
du 10 février 2021 (les plus récentes au moins de la rédaction de ce
billets) et pour un disque dur apparaissant en &lt;code&gt;/dev/sdb&lt;/code&gt;. Surtout
n’exécuter pas ces instructions sans les comprendre et sans changer la
valeur &lt;code&gt;/dev/sdb&lt;/code&gt;, au risque d’écraser toutes les données d’un disque dur
branché à l’ordinateur d’où vous les lancerez.
&lt;/p&gt;

&lt;div class="org-src-container"&gt;
&lt;pre class="src src-bash"&gt;wget https://raspi.debian.net/verified/20210210_raspi_4_buster.img.xz
wget https://raspi.debian.net/verified/20210210_raspi_4_buster.xz.sha256
sha256sum --check 20210210_raspi_4_buster.xz.sha256
xzcat 20210210_raspi_4_buster.img.xz | sudo dd &lt;span style="color: #9c36b5;"&gt;of&lt;/span&gt;=/dev/sdb &lt;span style="color: #9c36b5;"&gt;bs&lt;/span&gt;=64k &lt;span style="color: #9c36b5;"&gt;oflag&lt;/span&gt;=dsync &lt;span style="color: #9c36b5;"&gt;status&lt;/span&gt;=progress
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Ensuite, il n’y a plus qu’à retirer la carte SD du Raspberry Pi&lt;sup&gt;&lt;a id="fnr.1" class="footref" href="https://michael.parienti.net/posts/2021/03/16/booter-en-arm64-sur-un-disque-externe-son-raspberrypi4/#fn.1"&gt;1&lt;/a&gt;&lt;/sup&gt;, brancher le disque dur et redémarrer votre
framboise.
&lt;/p&gt;




&lt;h2&gt;En guise de conclusion&lt;/h2&gt;

&lt;p&gt;
Et voilà, votre Raspberry Pi 4 contient une debian ARM64 pur jus, et il
démarre sur un disque dur externe, généralement plus fiable que les carte
SD.
&lt;/p&gt;

&lt;p&gt;
À partir de là, à vous de continuer. Vous avez maintenant à disposition tous
les &lt;a href="https://packages.debian.org/stable/"&gt;paquets&lt;/a&gt; debian, il y a de quoi vous occuper :-)
&lt;/p&gt;


&lt;div id="footnotes"&gt;
&lt;h2 class="footnotes"&gt;Notes de bas de page: &lt;/h2&gt;
&lt;div id="text-footnotes"&gt;

&lt;div class="footdef"&gt;&lt;sup&gt;&lt;a id="fn.1" class="footnum" href="https://michael.parienti.net/posts/2021/03/16/booter-en-arm64-sur-un-disque-externe-son-raspberrypi4/#fnr.1"&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;div class="footpara"&gt;&lt;p class="footpara"&gt;
Ce n’est pas nécessaire si vous avez configurer le démarage sur
disque dur externe avant le démarrage sur carte SD
&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;/div&gt;</description><category>Debian</category><category>raspberry</category><guid>https://michael.parienti.net/posts/2021/03/16/booter-en-arm64-sur-un-disque-externe-son-raspberrypi4/</guid><pubDate>Tue, 16 Mar 2021 06:35:00 GMT</pubDate></item></channel></rss>