mouret.pro
Retour au Blog
macos bash automatisation fswatch

Surveiller un dossier et exécuter un script sur macOS avec fswatch

9 mars 2026 3 min de lecture Human Score C
Surveiller un dossier et exécuter un script sur macOS avec fswatch

Votre dossier Downloads ressemble à une décharge numérique. Des PDF mélangés avec des screenshots, des .zip, des .dmg. Vous rangez de temps en temps, puis ça recommence.

macOS ne propose rien de natif pour réagir à l’arrivée d’un fichier dans un dossier. Mais fswatch, un petit utilitaire en ligne de commande, fait exactement ça. Il surveille un dossier et exécute ce que vous voulez à chaque changement.

Installer fswatch

Un brew install et c’est réglé :

brew install fswatch

Si vous n’avez pas Homebrew, installez-le d’abord depuis brew.sh.

Pour vérifier que tout fonctionne :

fswatch --version

Le script de tri automatique

L’idée : chaque fichier qui arrive dans ~/Downloads est déplacé dans un sous-dossier selon son extension. Les images dans Images/, les PDF dans Documents/, les archives dans Archives/.

Créez un fichier ~/scripts/sort-downloads.sh :

#!/bin/bash

WATCH_DIR="$HOME/Downloads"
IMAGES_DIR="$WATCH_DIR/Images"
DOCS_DIR="$WATCH_DIR/Documents"
ARCHIVES_DIR="$WATCH_DIR/Archives"

mkdir -p "$IMAGES_DIR" "$DOCS_DIR" "$ARCHIVES_DIR"

fswatch -0 --event Created "$WATCH_DIR" | while IFS= read -r -d '' file; do
    # Ignorer les dossiers
    [ -d "$file" ] && continue

    basename=$(basename "$file")
    ext="${basename##*.}"
    ext=$(echo "$ext" | tr '[:upper:]' '[:lower:]')

    sleep 1  # attendre que le fichier soit completement ecrit

    case "$ext" in
        jpg|jpeg|png|gif|webp|heic)
            mv "$file" "$IMAGES_DIR/" 2>/dev/null
            echo "Image deplacee : $basename"
            ;;
        pdf|doc|docx|xls|xlsx|csv)
            mv "$file" "$DOCS_DIR/" 2>/dev/null
            echo "Document deplace : $basename"
            ;;
        zip|tar|gz|rar|7z|dmg)
            mv "$file" "$ARCHIVES_DIR/" 2>/dev/null
            echo "Archive deplacee : $basename"
            ;;
    esac
done

Rendez-le exécutable :

chmod +x ~/scripts/sort-downloads.sh

Lancez-le pour tester : ./scripts/sort-downloads.sh. Glissez un PNG dans Downloads, il atterrit dans Downloads/Images/. Les fichiers qui ne correspondent à aucune règle restent en place.

Comprendre fswatch

fswatch utilise les API natives de macOS (FSEvents) pour détecter les changements sur le système de fichiers. Pas de polling, pas de boucle qui tourne en consommant du CPU. Le système notifie fswatch quand quelque chose bouge.

Le flag --event Created limite la surveillance aux nouveaux fichiers. Sans ce filtre, fswatch réagit aussi aux modifications et suppressions. Le -0 sépare les résultats par des caractères null plutôt que des sauts de ligne, ce qui gère correctement les noms de fichiers avec des espaces.

Le sleep 1 n’est pas cosmétique. Quand un navigateur télécharge un fichier, il crée d’abord un fichier temporaire puis le renomme. Sans ce délai, le script peut tenter de déplacer un fichier qui n’est pas encore complet.

Lancer au démarrage avec un LaunchAgent

Le script fonctionne, mais il faut le relancer manuellement à chaque redémarrage. Un LaunchAgent résout ça.

Créez le fichier ~/Library/LaunchAgents/com.user.sort-downloads.plist :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.user.sort-downloads</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/VOTRE_USER/scripts/sort-downloads.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/tmp/sort-downloads.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/sort-downloads.err</string>
</dict>
</plist>

Remplacez VOTRE_USER par votre nom d’utilisateur, puis activez-le :

launchctl load ~/Library/LaunchAgents/com.user.sort-downloads.plist

KeepAlive redémarre le script s’il plante. Les logs vont dans /tmp/sort-downloads.log pour débuguer si besoin.

Pour le désactiver :

launchctl unload ~/Library/LaunchAgents/com.user.sort-downloads.plist

Adapter le principe a vos besoins

Le tri de fichiers est un exemple parmi d’autres. Le même pattern - fswatch + script bash - s’applique à beaucoup de situations.

Si vous automatisez déjà d’autres parties de votre workflow avec des outils comme n8n ou des scripts d’export Apple Notes, fswatch complète bien la panoplie pour tout ce qui touche au système de fichiers local.

Tous les articles