Retour au cours

infra / linux-bash

Recherche de fichiers (find, xargs)

Leçon 121 exercice

Explication

ls liste ce qui est présent dans un dossier, mais il ne sait pas chercher selon un critère. find, lui, explore récursivement une arborescence entière en évaluant des critères comme le nom, le type, la date de modification, la taille, les permissions ou le propriétaire — l'outil à utiliser dès que la recherche dépasse "je sais exactement où il est et comment il s'appelle".

Ce que vous allez apprendre

  • Rechercher des fichiers selon leur nom, leur type, leur date ou leur taille avec find
  • Combiner plusieurs critères de recherche en une seule commande
  • Agir directement sur les résultats trouvés avec -exec ou en les transmettant à xargs
  • Comprendre pourquoi -print0 / xargs -0 évitent des bugs avec les noms de fichiers à espaces
  • Choisir entre -exec ... + et -exec ... \; pour des raisons de performance

Dans quel contexte ?

Un administrateur système doit nettoyer un serveur qui manque d'espace disque : supprimer tous les fichiers .tmp de plus de 30 jours dans /var/tmp/, sans toucher aux fichiers plus récents, et sans que le nettoyage échoue à cause d'un nom de fichier contenant un espace (fréquent avec des fichiers uploadés depuis une interface web). C'est exactement le genre de tâche pour laquelle find combiné à xargs a été conçu.

Une fois qu'on sait trouver, il reste un problème : agir sur les résultats

find sait trouver des fichiers, mais il n'est pas toujours pratique pour agir efficacement sur des milliers de résultats à la fois. C'est là qu'intervient xargs, qui prend une liste de résultats et les transforme en arguments pour une autre commande. Cette combinaison illustre encore une fois la philosophie Unix : un outil trouve, un autre agit, et le pipe les relie entre eux.

Critère findExempleUsage typique
Nom-name "*.log"Cibler un type de fichier
Date de modification-mtime +30Fichiers vieux de plus de 30 jours
Taille-size +100MGros fichiers qui saturent le disque
Propriétaire-user nedAudit de fichiers appartenant à un utilisateur

Prérequis

Il faut être à l'aise avec les pipes (leçon précédente) : find et xargs se combinent presque toujours via |.

Un piège fréquent avec les noms de fichiers

Par défaut, find et xargs séparent les résultats par des espaces ou des retours à la ligne. Si un nom de fichier contient lui-même un espace, ce qui est fréquent avec des fichiers créés depuis une interface graphique, la commande peut être scindée n'importe où.

Piège dangereux

find . -name "*.tmp" | xargs rm -f sur un fichier nommé rapport final.tmp scinde le nom en deux arguments (rapport et final.tmp), ce qui peut provoquer une erreur ou, pire, supprimer un fichier différent portant le nom rapport. Les options -print0 et xargs -0 évitent ce problème en séparant les résultats par un caractère NUL, qui ne peut jamais apparaître dans un nom de fichier.

Une dernière nuance importante : -exec ... + contre -exec ... \;

Terminer une commande -exec par \; lance une nouvelle instance du programme pour CHAQUE fichier trouvé, ce qui peut devenir très lent sur de gros volumes. Terminer par + regroupe au contraire les fichiers en un minimum d'appels — une optimisation simple en apparence, mais qui change radicalement les performances sur des milliers de fichiers.

Maintenant que tu sais retrouver des fichiers avec précision, la prochaine étape logique est de savoir les regrouper et les compresser pour les archiver ou les transférer.

Commandes & code

Recherche de fichiers (find, xargs)

bash
find . -name "*.log"                     # par nom (sensible à la casse)
find . -iname "*.LOG"                      # insensible à la casse
find /var/log -maxdepth 1 -name "*.log"      # limite la profondeur de recherche
find . -type f                                 # uniquement les fichiers
find . -type d                                   # uniquement les dossiers
find . -type l                                     # uniquement les liens symboliques

find . -mtime -7                    # modifiés il y a moins de 7 jours
find . -mtime +30                     # modifiés il y a plus de 30 jours
find . -newer reference.txt             # plus récents qu'un fichier de référence
find . -size +100M                        # fichiers de plus de 100 Mo
find . -size -1k                            # fichiers de moins de 1 Ko
find . -empty                                 # fichiers ou dossiers vides

find . -perm 777                    # permissions exactement 777
find . -perm -u+x                     # exécutable par le propriétaire (au minimum)
find / -user ned                        # appartenant à un utilisateur précis
find / -group docker                      # appartenant à un groupe précis

# Combiner des critères
find . -type f -name "*.tmp" -mtime +7 -size +0

# Actions directes avec -exec
find . -name "*.tmp" -exec rm {} \;              # {} = chemin trouvé, \; termine la commande
find . -name "*.sh" -exec chmod +x {} \;
find . -name "*.log" -mtime +30 -exec rm -f {} +   # "+" regroupe les fichiers (bien plus rapide)

# find + xargs : la combinaison la plus performante pour de gros volumes
find . -name "*.tmp" -print0 | xargs -0 rm -f
# -print0 / -0 séparent par NUL au lieu d'espace : gère les noms de fichiers avec espaces/accents

find . -name "*.py" -print0 | xargs -0 -n1 -P4 pylint    # parallélise le traitement (4 process)

# Exclure des dossiers de la recherche (ex: .git, node_modules)
find . -path ./node_modules -prune -o -name "*.js" -print
find . \( -path ./.git -o -path ./node_modules \) -prune -o -type f -print

# locate : plus rapide que find mais dépend d'un index (à mettre à jour)
sudo updatedb
locate nginx.conf

Résumé

  • find combine des critères (nom, type, date, taille, permissions, propriétaire).
  • -exec ... + regroupe les fichiers en un minimum d'appels, bien plus rapide que -exec ... \;.
  • -print0 / xargs -0 sont indispensables dès que des noms de fichiers contiennent des espaces.

Exercices pratiques

1 disponible
1

Mission : nettoyer un serveur saturé sans supprimer le mauvais fichier

Objectif : Cibler précisément des fichiers avec find, les supprimer en toute sécurité malgré des noms à espaces, et choisir la bonne stratégie -exec.

Contexte

Le serveur manque d'espace disque. Tu dois supprimer tous les fichiers .tmp de plus de 30 jours dans /var/tmp/, sans toucher aux fichiers plus récents ni aux dossiers eux-mêmes, et sans que le nettoyage échoue à cause d'un nom de fichier contenant un espace (fréquent avec des uploads web).

Résoudre l’exercice →