---
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.
