Mirror the French docs onto the English structure
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Mes bêtises
|
||||
description: Petits projets Python et Bash, scripts et outils écrits pour résoudre des problèmes précis de homelab, en marge des guides Serveex.
|
||||
navigation:
|
||||
icon: i-lucide-bookmark
|
||||
---
|
||||
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
## Petits scripts et projets annexes
|
||||
|
||||
Tout ne rentre pas dans un guide « installez cette application ». Cette section rassemble les petits projets Python et Bash écrits en chemin : des scripts qui automatisent une corvée précise, collent deux applications ensemble, ou grattent là où ça démange. Moins peaufinés que [Serveex](/serveex/introduction), mais souvent plus amusants.
|
||||
|
||||
### Python
|
||||
|
||||
:::div{class="relative"}
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||
:::
|
||||
|
||||
::card-group
|
||||
::card
|
||||
---
|
||||
icon: i-simple-icons-nvidia
|
||||
title: Nvidia Stock Bot
|
||||
to: /nonsense/python/nvidia-stock-bot
|
||||
ui:
|
||||
icon: text-[#76B900]
|
||||
---
|
||||
Des alertes Discord sur la disponibilité des GPU
|
||||
::
|
||||
|
||||
::card
|
||||
---
|
||||
icon: i-cbi-adguard
|
||||
title: Adguard CIDRE
|
||||
to: /nonsense/python/adguard-cidre
|
||||
ui:
|
||||
icon: text-[#68BC71]
|
||||
---
|
||||
Synchroniser automatiquement les listes CIDR d'AdGuard Home
|
||||
::
|
||||
|
||||
::card{icon="i-brand-lumeex" title="Lumeex" to="/nonsense/python/lumeex"}
|
||||
Un générateur de galerie photo statique minimaliste
|
||||
::
|
||||
|
||||
::card{icon="i-brand-instameex" title="Instameex" to="/nonsense/python/instameex"}
|
||||
Fusionner des exports SDR/HDR pour Instagram HDR
|
||||
::
|
||||
::
|
||||
|
||||
### Bash
|
||||
|
||||
:::div{class="relative"}
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px}
|
||||
:::
|
||||
|
||||
::card-group
|
||||
::card{icon="i-lucide-copy-check" title="Servarr corrector" to="/nonsense/bash/servarr-duplicates"}
|
||||
Dédoublonner les bibliothèques Sonarr/Radarr avec des hardlinks
|
||||
::
|
||||
|
||||
::card{icon="i-lucide-lock-keyhole" title="LUKS Backup" to="/nonsense/bash/luks-backup"}
|
||||
Sauvegarder les en-têtes LUKS des disques chiffrés
|
||||
::
|
||||
|
||||
::card{icon="i-lucide-shield" title="Socat Proxy" to="/nonsense/bash/socat-proxy"}
|
||||
Monter le proxy du socket Docker pour les conteneurs en mode host
|
||||
::
|
||||
|
||||
::card{icon="i-lucide-thermometer" title="HotDisk" to="/nonsense/bash/hotdisk"}
|
||||
Éteindre le serveur si les disques surchauffent
|
||||
::
|
||||
|
||||
::card{icon="i-lucide-database-backup" title="Backrest Docker Stop" to="/nonsense/bash/backrest-docker-stop"}
|
||||
Arrêter proprement les conteneurs autour d'une sauvegarde Backrest
|
||||
::
|
||||
|
||||
::card{icon="i-lucide-shield-alert" title="rm Confirmation Guard" to="/nonsense/bash/rm-confirmation"}
|
||||
Un wrapper sudo qui demande confirmation avant de laisser passer rm
|
||||
::
|
||||
::
|
||||
+4
-9
@@ -1,14 +1,10 @@
|
||||
---
|
||||
title: Nvidia Stock Bot
|
||||
description: Un bot Python qui surveille la disponibilité des GPU en temps réel et envoie des alertes Discord — créé lors de la pénurie de la série RTX 5000.
|
||||
description: Un bot Python qui surveille la disponibilité des GPU en temps réel et envoie des alertes Discord, créé lors de la pénurie de la série RTX 5000.
|
||||
---
|
||||
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
# Scripts python
|
||||
|
||||
Mes cochonneries en python
|
||||
|
||||
## 🤖 Nvidia Stock Bot
|
||||
|
||||
Depuis déjà 4 ans, la pénurie de materiel electronique fait rage. Et les cartes graphiques ne sont pas épargnées. En 2020, j'ai du attendre 2 mois pour obtenir mon exemplaire de RTX 3080, et pour cela j'ai du m'inscrire sur [JV Hardware](https://discord.gg/gxffg3GA96) où une poignée de geek avait mis en place un bot qui envoyait un ping lorsqu'elles étaient disponibles.
|
||||
|
||||
@@ -32,7 +28,6 @@ J'ai également eu la chance d'être référencé dans la fameuse [newsletter se
|
||||
|
||||
Plus d'infos directement sur le repo :
|
||||
|
||||
|
||||
::card{title="🐋 __Nvidia Stock Bot__"}
|
||||
[Robot d'alerte de stock de GPU Nvidia](https://git.djeex.fr/Djeex/nvidia-stock-bot)
|
||||
::card{title="🐋 __Nvidia Stock Bot__" to="https://git.djeex.fr/Djeex/nvidia-stock-bot" target="_blank"}
|
||||
Robot d'alerte de stock de GPU Nvidia
|
||||
::
|
||||
+1
-2
@@ -3,8 +3,8 @@ title: Adguard CIDRE
|
||||
description: Un script Python pour synchroniser automatiquement les listes CIDR d'AdGuard Home et sécuriser votre serveur DNS auto-hébergé exposé sur internet.
|
||||
---
|
||||
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
# 🤖 Adguard CIDRE Sync
|
||||
|
||||
Adguard Home est une solution merveilleuse pour filter ses requêtes DNS et ainsi se débarasser de la publicité ou des DNS des fournisseurs d'accès, ou encore réécrire des requetes.
|
||||
|
||||
@@ -28,7 +28,6 @@ Tout ceci de manière complètement autonome, avec une fréquence choisie en var
|
||||
|
||||
Plus d'infos directement sur le repo :
|
||||
|
||||
|
||||
::card{title="🐋 __Adguard CIDRE Sync__"}
|
||||
[Robot de synchronisation de la blocklist d'Adguard](https://git.djeex.fr/Djeex/adguard-cidre)
|
||||
::
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Lumeex
|
||||
description: Lumeex est un générateur de galerie photo statique en Python — minimaliste, léger et entièrement personnalisable sans CMS.
|
||||
description: Lumeex est un générateur de galerie photo statique en Python, minimaliste, léger et entièrement personnalisable sans CMS.
|
||||
---
|
||||
|
||||
|
||||
-1
@@ -14,7 +14,6 @@ description: Instameex est un outil Docker pour fusionner des exports SDR et HDR
|
||||
<div align="center">
|
||||
<img src="https://git.djeex.fr/Djeex/instameex/raw/branch/main/illustration/instameex-illustration.png" width="640" alt="Instameex Screenshot" />
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
Il n'y a rien de plus frustrant que la gestion du HDR d'Instagram. Ce dernier compresse et démolit les gainmaps, et au moindre changement de ratio ou de taille, supprime purement et simplement le HDR. Quant à Lightroom, son système de "SDR preview" est tout bonnement inacceptable, ne permettant pas d'obtenir des résultats corrects. Jusqu'ici, lorsque l'on veut poster sur Instagram, il faut choisir entre un SDR potable et un HDR déficient, ou l'inverse.
|
||||
+17
-14
@@ -3,24 +3,26 @@ title: Doublons servarr
|
||||
description: Un script bash pour détecter et corriger les fichiers médias en double dans les bibliothèques Sonarr et Radarr en remplaçant les copies par des hardlinks.
|
||||
---
|
||||
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
# Detection de doublons et remplacement par des hardlinks
|
||||
|
||||
Six mois après avoir téléchargé des térabytes de media, je me suis rendu compte que Sonarr et Radarr les copaient dans ma biblio Plex au lieu de créer des hardlinks. C'est dû à un mécanisme contre intuitif qui est que si vous montez plusieurs dossiers dans Sonarr/Radarr, il les voit comme deux systemes de fichiers différents. Et ne peut donc pas créer de hardlinks. C'est pour cela qu'il ne faut monter qu'un seul dossier parent, qui contient tous les enfants (`downloads`, `movies`, `tvseries` dans le dossier parent `media` par exemple).
|
||||
|
||||
J'ai donc restructuré mes dossiers, remis à la main chaque chemin dans Qbittorrent, Plex, et autres. Il restait à trouver un moyen de détecter les doublons existants et d'automatiquement les supprimer et de créer des hardlinks à la place, pour économiser de l'espace.
|
||||
|
||||
Mes dossiers :
|
||||
|
||||
```text [Arborescence]
|
||||
.
|
||||
└── media
|
||||
├── seedbox
|
||||
├── radarr
|
||||
│ └── tv-radarr
|
||||
├── movies
|
||||
└── tvseries
|
||||
```
|
||||
::file-tree
|
||||
---
|
||||
label: Mes dossiers
|
||||
tree:
|
||||
.:
|
||||
- media:
|
||||
- seedbox/
|
||||
- radarr:
|
||||
- tv-radarr/
|
||||
- movies/
|
||||
- tvseries/
|
||||
---
|
||||
::
|
||||
|
||||
Mes dossiers originaux sont dans `seedbox`, et il ne faut surtout pas les modifier pour qu'ils continuent d'etre "seed". Les copies, et donc doublons, sont dans `movies` et `tvseries`. Mais pour complexifier la chose, j'ai aussi des media uniques originaux déposés par ailleurs dans `movies` et `tvseries`, sinon cela serait trop facile. Et dans ces deux dossiers, il peut y avoir des sous dossiers, des sous-sous dossiers, etc.
|
||||
|
||||
@@ -52,7 +54,7 @@ while IFS= read -r -d '' file; do
|
||||
# Obtenir l'inode du fichier et son chemin
|
||||
inode=$(stat --format="%i" "$file")
|
||||
filename=$(basename "$file")
|
||||
|
||||
|
||||
# Si ce nom de fichier a déjà été vu
|
||||
if [[ -n "${seen[$filename]}" ]]; then
|
||||
# Vérifier si l'inode est différent du précédent
|
||||
@@ -64,7 +66,6 @@ while IFS= read -r -d '' file; do
|
||||
echo
|
||||
fi
|
||||
else
|
||||
# Si c'est la première fois qu'on rencontre ce nom de fichier
|
||||
seen[$filename]="$inode"
|
||||
seen["$filename:full_path"]="$file"
|
||||
fi
|
||||
@@ -82,7 +83,9 @@ Doublons pour "episode1.mkv" :
|
||||
Avec "awk", il se serait arrêté à `/media/seedbox/sonarr/Serie`. Je ne suis absolument pas un pro, mais Qwen3 a été plus performant et m'a expliqué de A à Z pourquoi et comment faire.
|
||||
|
||||
Une fois que j'ai vu que cela fonctionnait bien, j'ai demandé un script qui fait l'intégralité de la cinématique, de la comparaison aux hardlinks en passant par la suppression des doublons.
|
||||
|
||||
Encore une fois ChatGPT a été décevant. Malgré mes demandes, il créait d'abord les hardlinks et ensuite il supprimait les doublons. Ce qui.. suprimme aussi le lien (meme si cela conserve l'originale). Idiot.
|
||||
|
||||
Petit détour par Qwen3, et ma RTX 5090 en PLS, et paf un résultat bien plus propre. Bon il a gardé les emoji de ChatGPT qui peut pas s'empecher d'en mettre partout, mais voilà :
|
||||
|
||||
```bash [Terminal]
|
||||
+1
-1
@@ -3,8 +3,8 @@ title: Luks backup
|
||||
description: Un script bash pour extraire automatiquement les headers LUKS de tous les disques chiffrés, les identifier par numéro de série et les archiver de façon chiffrée.
|
||||
---
|
||||
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
# Backup des headers luks pour disques/volumes chiffrés
|
||||
|
||||
Je me suis rendu compte il y a peu qu'il ne suffisait pas d'avoir le mot de passe pour deverouiller un volume luks apres une panne ou une corruption. J'ai ainsi appris à dump les headers luks des disques/volumes et à utiliser les numéros de série + noms de partitions pour pouvoir bien identifier quel header correspond à quel disque/partition (j'en ai 10 !).
|
||||
|
||||
+1
-3
@@ -3,9 +3,8 @@ title: Socat Proxy
|
||||
description: Utiliser socat pour proxifier le socket Docker via Docker Socket Proxy, permettant à Beszel de collecter les stats des conteneurs sans exposer le socket complet.
|
||||
---
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
# Socat Proxy
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
Ce projet répond à un cas d'usage problématique :
|
||||
|
||||
- J'ai [Beszel](https://beszel.dev/), un conteneur de monitoring en mode host, nécessitant d'exposer le socket de Docker afin qu'il récupère les stats des conteneurs
|
||||
@@ -78,7 +77,6 @@ services:
|
||||
|
||||
Plus d'infos directement sur le repo :
|
||||
|
||||
|
||||
::card{title="🐋 __Socat Proxy__"}
|
||||
[A lighteweight bind mount socket proxy](https://git.djeex.fr/Djeex/socat-proxy)
|
||||
::
|
||||
+11
-8
@@ -3,10 +3,12 @@ title: HotDisk
|
||||
description: Un script bash qui surveille la température des disques durs et éteint automatiquement le serveur lorsqu'ils dépassent un seuil de sécurité trop longtemps.
|
||||
---
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
# HotDisk
|
||||
|
||||
Quand on a un NAS avec plusieurs disques dans une buanderie, les températures peuvent vite grimper. Or, un disque dur est très sensible aux températures et peut subir de gros dommages s'il dépasse une température seuil pendant un certain temps. Après un été très chaud qui a fournit son lot de sueur froide en regardant la température de mes disques, j'ai cherché un moyen de pouvoir automatiser l'extinction du serveur en cas de dépassement prolonger de la température maximale supportée par mes disques.
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
|
||||
Quand on a un NAS avec plusieurs disques dans une buanderie, les températures peuvent vite grimper.
|
||||
Un disque dur est très sensible à la chaleur et peut subir de gros dommages s'il dépasse une température seuil trop longtemps.
|
||||
Après un été très chaud qui a fournit son lot de sueur froide en regardant la température de mes disques, j'ai cherché un moyen de pouvoir automatiser l'extinction du serveur en cas de dépassement prolonger de la température maximale supportée par mes disques.
|
||||
|
||||
N'ayant rien trouvé de convaincant, je l'ai donc fait moi-même.
|
||||
|
||||
@@ -16,7 +18,8 @@ N'ayant rien trouvé de convaincant, je l'ai donc fait moi-même.
|
||||
- Il déclenche l’arrêt du système si la température dépasse la limite pendant la durée configurée.
|
||||
- Il enregistre toutes les températures et l’état des compteurs, et effectue automatiquement la rotation des journaux.
|
||||
|
||||
Puis tant qu'on y est, j'ai ajouté un script d'installation qui installe le script, le rend éxecutable, crée un service systemd et un timer systemd et l'active. Le script d'installation permet aussi de régler les différentes variables:
|
||||
Puis tant qu'on y est, j'ai ajouté un script d'installation qui installe le script principal, le rend exécutable, crée un service systemd et un timer, et les active automatiquement.
|
||||
Le script d'installation permet aussi de régler différents paramètres :
|
||||
|
||||
| Variable | Description | Valeur par défaut |
|
||||
|-----------------------|------------------------------------------------------------------------------|-----------------------------------------------|
|
||||
@@ -28,7 +31,8 @@ Puis tant qu'on y est, j'ai ajouté un script d'installation qui installe le scr
|
||||
| `LOG_ROTATE_PERIOD` | Période de rotation des journaux (`daily` ou `weekly`) | `daily` |
|
||||
| `DISCORD_WEBHOOK` | URL du webhook Discord pour les notifications | _Obligatoire_ |
|
||||
|
||||
Il execute aussi un autre script qui paramètre le logrotate avec les éléments configurés prédédemment. Et enfin, le script d'installation peut etre executé via un simple curl + execution d'un dernier script pour les plus flemmard.
|
||||
Il exécute aussi un autre script qui paramètre **logrotate** avec les éléments configurés précédemment.
|
||||
Et enfin, le script d'installation peut être exécuté directement via un simple `curl` suivi d'un dernier script de configuration, parfait pour les plus flemmards.
|
||||
|
||||
Il a fallu également gérer le sujet du root sans sudo, du sudo seul, de l'utilisateur sans sudo, les divers cas d'erreur (dépendances manquantes, erreur dans les permissions, créations de fichier, de lecture des données des disques, etc...)
|
||||
|
||||
@@ -36,7 +40,6 @@ Et l'acces concurrent au fichier de statuts.
|
||||
|
||||
Plus d'infos directement sur le repo :
|
||||
|
||||
|
||||
::card{title="📜 __HotDisk__"}
|
||||
[Gardez vos disques au frais !](https://git.djeex.fr/Djeex/hotdisk)
|
||||
::card{title="📜 __HotDisk__" to="https://git.djeex.fr/Djeex/hotdisk" target="_blank"}
|
||||
Gardez vos disques au frais !
|
||||
::
|
||||
+15
-11
@@ -1,16 +1,16 @@
|
||||
---
|
||||
title: Backrest Docker Stop
|
||||
description: Un script bash qui arrête les conteneurs Docker avant une sauvegarde Backrest et les redémarre après — pour des sauvegardes de bases de données sans dump complexe.
|
||||
description: Un script bash qui arrête les conteneurs Docker avant une sauvegarde Backrest et les redémarre après, pour des sauvegardes de bases de données sans dump complexe.
|
||||
---
|
||||
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
# Backrest Docker Stop
|
||||
|
||||
[Backrest](https://github.com/garethgeorge/backrest) est un formidable outil de backup. Dans le cas de [Serveex](https://docu.djeex.fr/fr/serveex/introduction), la majeure partie des données à sauvegarder sont des conteneurs, et souvent ces conteneurs possèdent des bases de données. Le problème ? On ne peut pas sauvegarder proprement une BDD qui est en route. Alors, il existe plein de solutions complexe à base de dump des bases de données, mais souvent le plus simple cela reste de stopper les conteneurs, de sauvegarder, et de redémarrer les conteneurs.
|
||||
[Backrest](https://github.com/garethgeorge/backrest) est un formidable outil de backup. Dans le cas de [Serveex](https://docu.djeex.fr/fr/serveex/introduction), la majeure partie des données à sauvegarder sont des conteneurs, et souvent ces conteneurs possèdent des bases de données.
|
||||
|
||||
**Backrest** ne propose pas de solutions native, mais il propose d'executer des scripts customisés à déclencher sur des évenements, comme le démarrage et la fin de la sauvegarde par exemple. Notre besoin est donc de stopper les conteneurs dont on veut sauvegarder la BDD, à chaque démarrage du plan de sauvegarde, et de les redémarrer à la fin de l'execution du plan de sauvegarde.
|
||||
Le problème ? On ne peut pas sauvegarder proprement une BDD qui est en route. Alors, il existe plein de solutions complexe à base de dump des bases de données, mais souvent le plus simple cela reste de stopper les conteneurs, de sauvegarder, et de redémarrer les conteneurs.
|
||||
|
||||
Pour cela nous allons avoir besoin d'un script bash et de connecter Backrest au socker de Docker, afin d'avoir la cinématique suivante :
|
||||
**Backrest** ne propose pas de solutions native, mais il propose d'executer des scripts customisés à déclencher sur des évenements, comme le démarrage et la fin de la sauvegarde par exemple. Notre besoin est donc de stopper les conteneurs dont on veut sauvegarder la BDD, à chaque démarrage du plan de sauvegarde, et de les redémarrer à la fin de l'execution du plan de sauvegarde. Pour cela nous allons avoir besoin d'un script bash et d'une connexion sécurisée entre Backrest et le socket de Docker, afin d'avoir la cinématique suivante :
|
||||
|
||||
- Le plan de sauvegarde se met en route
|
||||
- L'evenement déclenche l'execution d'un script custom
|
||||
@@ -18,12 +18,13 @@ Pour cela nous allons avoir besoin d'un script bash et de connecter Backrest au
|
||||
- Il récupère cette liste et leur envoie une commande d'extinction
|
||||
- Le plan de sauvegarde s'arrête
|
||||
- L'evenement déclenche l'execution d'un script custom
|
||||
- Le script contacte docker et demande la liste des conteneurs qui comportent le label `backrest.backup.stop=true`
|
||||
- Il récupère cette liste et leur envoie une commande de démarrage
|
||||
- Le script recontacte docker, récupère la même liste, et redémarre ces conteneurs
|
||||
|
||||
## Faire communiquer Backrest et Docker en toute sécurité
|
||||
|
||||
Pour faire communiquer **Backrest** et Docker en toute sécurité, nous utiliserons [Docker Socket Proxy](https://github.com/linuxserver/docker-socket-proxy), afin de n'accorder que les droits nécessaires plutot que d'exposer l'intégralité du socket à Docker. Voici donc la stack :
|
||||
Pour faire communiquer **Backrest** et Docker en toute sécurité, nous utiliserons [Docker Socket Proxy](https://github.com/linuxserver/docker-socket-proxy).
|
||||
Cela évite d'exposer l'intégralité du socket Docker et n'accorde que les droits nécessaires.
|
||||
Voici un exemple de stack Docker :
|
||||
|
||||
```yaml [compose.yaml]
|
||||
---
|
||||
@@ -80,6 +81,7 @@ do
|
||||
done
|
||||
sleep 10
|
||||
```
|
||||
|
||||
```sh [Start]
|
||||
#!/usr/bin/env bash
|
||||
|
||||
@@ -93,7 +95,8 @@ sleep 10
|
||||
```
|
||||
::
|
||||
|
||||
## Le label
|
||||
## Le label
|
||||
|
||||
Une fois les scripts renseignés et paramétrés pour les bons hooks dans **Backrest**, vous n'avez plus qu'à ajouter le libellé `backrest.backup.stop=true` dans les fichiers `compose.yaml` des conteneurs à éteindre et rallumer durant les sauvegardes :
|
||||
|
||||
```yaml [compose.yaml]
|
||||
@@ -102,7 +105,8 @@ services:
|
||||
votre_service:
|
||||
...
|
||||
labels:
|
||||
- com.centurylinklabs.watchtower.enable=true
|
||||
- backrest.backup.stop=true
|
||||
```
|
||||
|
||||
Et voilà, à la prochaine sauvegarde, les conteneurs correctement labelisés s'arreteront pendant la sauvegarde et redémarreront tout seuls à la fin.
|
||||
Et voilà !
|
||||
À la prochaine sauvegarde, les conteneurs correctement labelisés s'arrêteront pendant la sauvegarde et redémarreront tout seuls une fois terminée.
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: rm Confirmation Guard
|
||||
description: Une petite fonction Bash qui enveloppe sudo et demande confirmation avant de lancer rm, pour qu'une faute de frappe n'efface pas des fichiers appartenant à root.
|
||||
---
|
||||
|
||||
|
||||
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||
|
||||
`rm` ne demande pas deux fois. Pas de corbeille, pas de « êtes-vous sûr », surtout pas avec `sudo` devant, où un espace de trop ou la mauvaise variable peut effacer quelque chose que vous n'avez pas la permission de revérifier. C'est la seule habitude vraiment destructrice qu'un terminal vous inculque, et le correctif ne demande aucun outil supplémentaire, juste quelques lignes dans `.bashrc`.
|
||||
|
||||
L'idée est de masquer la commande `sudo` par une fonction Bash du même nom. Tous les autres usages de `sudo` passent toujours directement, mais dès que le premier argument est `rm`, elle s'arrête et pose la question.
|
||||
|
||||
```bash [.bashrc]
|
||||
# rm confirmation
|
||||
sudo() {
|
||||
if [ "$1" = "rm" ]; then
|
||||
echo -n "Are you sure you want to delete files/folders with sudo? (y/n) "
|
||||
read ans
|
||||
if [[ $ans == [Yy]* ]]; then
|
||||
command sudo rm "${@:2}"
|
||||
else
|
||||
echo "Deletion cancelled."
|
||||
fi
|
||||
else
|
||||
command sudo "$@"
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
## Comment ça marche
|
||||
|
||||
- `sudo() { ... }` définit une fonction nommée `sudo`. Bash cherche les fonctions avant de chercher les commandes du `PATH`, donc taper `sudo` dans un terminal lance désormais celle-ci au lieu de `/usr/bin/sudo`, sans aucune bidouille d'alias.
|
||||
- `if [ "$1" = "rm" ]` ne regarde que le tout premier mot après `sudo`. `sudo rm -rf /srv/docker/vieille-stack` correspond, `sudo apt update` non.
|
||||
- En cas de correspondance, elle affiche la question, lit la réponse dans `$ans`, et `[[ $ans == [Yy]* ]]` accepte `y`, `Y`, `yes`, tout ce qui commence par un Y dans l'une ou l'autre casse.
|
||||
- `command sudo rm "${@:2}"` est la partie qui supprime réellement. `command` contourne la fonction pour qu'elle ne s'appelle pas elle-même, et `${@:2}` représente tous les arguments après `rm`, donc `-rf /srv/docker/vieille-stack` est transmis tel quel.
|
||||
- Tout ce qui n'est pas `rm` tombe dans le `else` et s'exécute exactement comme si la fonction n'existait pas : `command sudo "$@"`.
|
||||
|
||||
## L'installer
|
||||
|
||||
::steps{level="3"}
|
||||
### Ouvrir la config de votre shell
|
||||
|
||||
```bash [Terminal]
|
||||
nano ~/.bashrc
|
||||
```
|
||||
|
||||
### Coller la fonction
|
||||
|
||||
Ajoutez le bloc ci-dessus à la fin du fichier, puis enregistrez et quittez.
|
||||
|
||||
### Recharger
|
||||
|
||||
```bash [Terminal]
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
### Essayer
|
||||
|
||||
```console [Terminal]
|
||||
$ sudo rm -rf /tmp/test
|
||||
Are you sure you want to delete files/folders with sudo? (y/n) n
|
||||
Deletion cancelled.
|
||||
```
|
||||
|
||||
Répondez `y` et elle s'exécute pour de vrai. Tout ce qui n'est pas `rm`, `sudo apt update`, `sudo systemctl restart docker`, passe sans question.
|
||||
|
||||
### Terminé !
|
||||
::
|
||||
|
||||
::note
|
||||
Tout ceci vit dans `~/.bashrc`, donc ne s'applique qu'à votre shell interactif, pas aux scripts, aux tâches cron ni à la session d'un autre utilisateur. C'est bien le but : attraper vous, en train de taper, pas un programme qui appelle `sudo rm` volontairement.
|
||||
::
|
||||
|
||||
## Ce que ça n'attrapera pas
|
||||
|
||||
C'est un garde-fou, pas un bac à sable. Il ne se déclenche que lorsque `rm` est littéralement le premier mot après `sudo`, donc tout ce qui atteint `rm` d'une autre façon passe à côté :
|
||||
|
||||
- `sudo -i rm -rf /` ou `sudo su -c "rm -rf /"`, le premier argument est `-i` ou `su`, pas `rm`
|
||||
- `sudo bash -c "rm -rf /srv/docker"`, même raison, `rm` est enfoui dans la chaîne que bash exécute
|
||||
- `sudo find /srv/docker -delete`, qui supprime tout aussi définitivement, et n'appelle jamais `rm`
|
||||
- `rm` sans `sudo` sur des fichiers qui vous appartiennent déjà
|
||||
|
||||
La vraie protection contre cette dernière catégorie, c'est une sauvegarde en bonne et due forme, [Backrest](https://github.com/garethgeorge/backrest) et le [script d'arrêt Docker](/nonsense/bash/backrest-docker-stop) traité ailleurs dans cette section, ou autre chose. Cette fonction vaut quand même le coup : les accidents qu'elle attrape sont ceux qui arrivent réellement, un `sudo rm -rf` tapé trop vite avec une faute dans le chemin, pas une tentative délibérée de la contourner.
|
||||
Reference in New Issue
Block a user