Quand on administre des serveurs ou des environnements de dev avec des arborescences profondes, on doit souvent retrouver vite un log énorme, un script perdu ou un répertoire précis. find parcourt le système de fichiers en temps réel et permet de sélectionner des fichiers (nom, type, taille, date, permissions) puis d'agir dessus (afficher, auditer, exécuter une commande, nettoyer).
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Cibler des fichiers par nom, type, taille, date, permissions
- Combiner des critères (AND/OR/NOT, parenthèses)
- Appliquer une action en sécurité (
-print→ puis-exec/-delete)
La commande find dans l'écosystème Linux
Section intitulée « La commande find dans l'écosystème Linux »find fait partie des commandes de recherche et de traitement de fichiers sous Linux. Chaque outil a sa spécialité :
| Commande | Spécialité | Quand l'utiliser |
|---|---|---|
find | Rechercher des fichiers par attributs | Trouver par nom, taille, date, permissions |
locate | Recherche ultra-rapide par nom | Quand la vitesse prime (base indexée) |
grep | Rechercher dans le contenu | Trouver une chaîne dans des fichiers |
which / whereis | Localiser des exécutables | Trouver où est installé un programme |
xargs | Exécuter des commandes en masse | Passer les résultats de find à une commande |
awk | Traiter des données tabulaires | Extraire/transformer des colonnes |
sed | Éditer des fichiers en flux | Remplacer du texte, supprimer des lignes |
cut | Extraire des colonnes | Découper par délimiteur ou position |
Combinaisons fréquentes :
# find + grep : chercher un motif dans certains fichiersfind /var/log -name '*.log' -exec grep -l "error" {} +
# find + xargs : traitement en masse (robuste avec espaces)find . -name '*.tmp' -print0 | xargs -0 rm -f
# locate + grep : filtrer les résultats de locatelocate '*.conf' | grep nginxComprendre la commande find en 2 min
Section intitulée « Comprendre la commande find en 2 min »🧠 Modèle mental — Comment fonctionne find
find = Où chercher → Quoi garder → Quoi faire
Points clés
- find parcourt un dossier et tous ses sous-dossiers
- Il garde les fichiers qui matchent tes critères (nom, type, date, taille)
- Plusieurs critères = ET (les deux doivent matcher)
- Si tu utilises OU (-o), pense aux parenthèses
- Tu peux exécuter une commande sur les fichiers trouvés (-exec)
- Tu peux supprimer des fichiers (-delete) MAIS toujours vérifier avant avec -print
Règles d'or
Vocabulaire essentiel
- -name '*.log'
- Fichiers dont le nom correspond au motif
- -type f / -type d
- Fichier (f) ou dossier (d)
- -mtime +7
- Modifié il y a plus de 7 jours
- -size +100M
- Taille supérieure à 100 Mo
- -maxdepth 2
- Ne pas descendre plus de 2 niveaux
- -print / -delete
- Afficher les résultats / Supprimer
📚 Pour aller plus loin — 12 options avancées
- -iname
- Comme -name mais insensible à la casse
- -path / -ipath
- Pattern sur le chemin complet
- -mmin -60
- Modifié il y a moins de 60 minutes
- -perm 644
- Permissions exactes
- -user / -group
- Par propriétaire ou groupe
- -prune
- Exclure un sous-arbre
- -xdev
- Ne pas traverser les points de montage
- -exec cmd {} \;
- Exécuter pour chaque fichier
- -exec cmd {} +
- Exécuter en batch (plus rapide)
- -ok cmd {} \;
- Comme -exec avec confirmation
- -printf FORMAT
- Sortie formatée personnalisée
- -quit
- Arrêter au premier résultat
Contrairement à locate (index pré-calculé), find ne dépend pas d'une base : le résultat reflète l'état actuel du disque.
Syntaxe minimale
Section intitulée « Syntaxe minimale »find [CHEMIN...] [FILTRES...] [ACTIONS...]Les 3 parties d'une commande find
Section intitulée « Les 3 parties d'une commande find »La commande find suit toujours la même logique en trois étapes :
| Étape | Question | Exemples | Obligatoire ? |
|---|---|---|---|
| Où chercher | Dans quel dossier démarrer ? | /var/log, ., /home | ⚠️ Implicite (défaut : .) |
| Quels résultats garder | Quels fichiers correspondent à mes critères ? | -name '*.log', -type f, -size +100M | ❌ Non (par défaut : tout) |
| Quoi faire | Quelle action effectuer sur les résultats ? | -print, -delete, -exec rm {} + | ❌ Non (par défaut : -print) |
Où chercher (optionnel) — C'est le point de départ. find va parcourir ce dossier et tous ses sous-dossiers récursivement. Si vous n'indiquez pas de chemin, c'est . qui sera utilisé (le répertoire courant).
Quels résultats garder (optionnel) — Ce sont les filtres. Si vous n'en mettez pas, find retourne tout. Vous pouvez combiner plusieurs critères : par défaut ils sont liés par ET (tous doivent correspondre).
Quoi faire (optionnel) — C'est l'action finale. Sans action explicite, find affiche simplement les chemins (-print). Pour des actions destructrices (-delete, -exec rm), testez toujours avec -print d'abord.
Les filtres : cibler précisément vos fichiers
Section intitulée « Les filtres : cibler précisément vos fichiers »Les filtres permettent de réduire les résultats aux fichiers qui vous intéressent. Voici les plus utilisés :
| Filtre | Ce qu'il teste | Exemple |
|---|---|---|
-name 'motif' | Nom du fichier (sensible à la casse) | -name '*.log' |
-iname 'motif' | Nom du fichier (insensible à la casse) | -iname '*.LOG' |
⚠️ Toujours mettre le motif entre quotes : -name '*.log'. Sinon le shell interprète * avant find et vous obtenez des résultats inattendus.
| Filtre | Ce qu'il teste | Exemple |
|---|---|---|
-type f | Fichiers uniquement | -type f |
-type d | Dossiers uniquement | -type d |
-size +100M | Taille supérieure à 100 Mo | -size +100M |
-size -1k | Taille inférieure à 1 Ko | -size -1k |
-mtime -7 | Modifié il y a moins de 7 jours | -mtime -7 |
-mtime +30 | Modifié il y a plus de 30 jours | -mtime +30 |
-user alice | Appartient à l'utilisateur alice | -user alice |
-perm 644 | Permissions exactement 644 | -perm 644 |
-perm -644 | Au moins ces bits (lecture/écriture) | -perm -644 |
-perm /222 | Au moins un bit d'écriture | -perm /222 |
Note sur les tailles : k, M, G sont pratiques mais l'interprétation peut varier selon les implémentations de find. En cas de doute, testez.
Combiner les filtres — ET / OU / NON :
Par défaut, les filtres sont combinés avec ET (tous doivent correspondre) :
# Fichiers .log ET de plus de 10 Mo (les deux conditions)find /var/log -type f -name '*.log' -size +10MAstuce : ajoutez -type f pour ne matcher que les fichiers (évite le bruit des répertoires).
Pour utiliser OU, ajoutez -o et des parenthèses (échappées) :
# Fichiers .log OU .txtfind /var/log -type f \( -name '*.log' -o -name '*.txt' \)Pourquoi \( et \) ? Le shell interprète les parenthèses nues. On les échappe (\( \)) ou on les met entre quotes ('(' ')').
Pour exclure par nom, utilisez ! ou -not :
# Tous les fichiers SAUF ceux commençant par .gitfind . -type f ! -name '.git*'⚠️ Attention : ceci n'exclut PAS le dossier .git/ du parcours ! Pour vraiment ignorer un dossier, utilisez -prune :
# Exclure le dossier .git de la recherche (correct)find . -name .git -prune -o -type f -printLes actions : que faire des fichiers trouvés ?
Section intitulée « Les actions : que faire des fichiers trouvés ? »Une fois les fichiers filtrés, vous pouvez agir dessus :
| Action | Ce qu'elle fait | Exemple |
|---|---|---|
-print | Affiche le chemin (par défaut) | -print |
-ls | Affiche en format ls -l | -ls |
-delete | Supprime le fichier | -delete |
-exec cmd {} \; | Exécute cmd sur chaque fichier | -exec chmod 644 {} \; |
-exec cmd {} + | Exécute cmd avec tous les fichiers | -exec rm {} + |
Règle d'or : toujours prévisualiser avant de détruire
# ❌ DANGEREUX : supprime directementfind /tmp -name '*.tmp' -delete
# ✅ SÛR : prévisualiser d'abordfind /tmp -name '*.tmp' -print# Vérifier la liste, puis seulement :find /tmp -name '*.tmp' -deleteAlternative robuste (gère les espaces et caractères spéciaux dans les noms) :
find . -type f -name '*.tmp' -print0 | xargs -0 rm -f-exec {} \; vs -exec {} + — La différence est importante :
\;: lance une commande par fichier (lent si beaucoup de fichiers)+: regroupe les fichiers et lance une seule commande (rapide, recommandé)
# Lent : 1000 fichiers = 1000 appels à chmodfind . -type f -exec chmod 644 {} \;
# Rapide : 1000 fichiers = quelques appels à chmodfind . -type f -exec chmod 644 {} +Contrôler le parcours : -depth et -prune
Section intitulée « Contrôler le parcours : -depth et -prune »Par défaut, find parcourt l'arborescence de haut en bas. Deux options modifient ce comportement :
-depth — Traite le contenu d'un dossier avant le dossier lui-même :
# Sans -depth : /tmp est listé AVANT son contenufind /tmp -type d
# Avec -depth : /tmp est listé APRÈS son contenufind /tmp -depth -type dC'est automatique avec -delete pour éviter de supprimer un dossier avant son contenu.
-prune — Stoppe la descente dans un dossier (utile pour exclure des répertoires) :
# Exclure le dossier node_modules de la recherchefind . -name 'node_modules' -prune -o -name '*.js' -print
# Exclure plusieurs dossiersfind . \( -name 'node_modules' -o -name '.git' \) -prune -o -type f -printComment lire -prune : "Si tu trouves ce dossier, ne descends pas dedans (-prune), sinon (-o) applique le reste."
| Option | Effet | Cas d'usage |
|---|---|---|
-depth | Traite enfants avant parents | Suppression récursive |
-prune | N'entre pas dans le dossier | Exclure node_modules, .git |
-maxdepth N | Limite la profondeur | find . -maxdepth 1 (niveau courant) |
-mindepth N | Ignore les N premiers niveaux | find . -mindepth 2 (sous-dossiers) |
Exemples pratiques :
# Lister uniquement le contenu immédiat (pas de récursion)find /var/log -maxdepth 1 -type f -name '*.log'
# Chercher à partir du 2e niveau (ignorer le dossier racine)find . -mindepth 2 -type f -name '*.conf'
# Combiner les deux : chercher entre le niveau 2 et 4find /home -mindepth 2 -maxdepth 4 -type d -name '.ssh'
# Supprimer des dossiers vides (depth nécessaire pour traiter enfants d'abord)find /tmp -depth -type d -empty -delete
# Lister les fichiers du niveau courant uniquement (équivalent de ls)find . -maxdepth 1 -type fErreurs typiques (et solutions)
Section intitulée « Erreurs typiques (et solutions) »| Erreur | Cause | Solution |
|---|---|---|
find -name *.log ne trouve rien | Le shell a interprété * avant find | Mettre entre quotes : -name '*.log' |
-o ne fonctionne pas comme prévu | Priorité des opérateurs | Ajouter des parenthèses : \( ... -o ... \) |
"J'ai exclu .git mais find cherche dedans" | ! -name n'empêche pas la descente | Utiliser -prune : -name .git -prune -o ... |
| Résultats incluent des répertoires | Pas de filtre -type | Ajouter -type f pour les fichiers uniquement |
Les modèles de recherche courants
Section intitulée « Les modèles de recherche courants »Maintenant que vous comprenez la logique de find, voici dix modèles prêts à l'emploi. Chacun donne sa formule générale et un exemple concret.
Recherche par nom exact
Section intitulée « Recherche par nom exact »Trouver un fichier dont on connaît le nom précis.
find <chemin> -name "<nom>" # formulefind /var/log -name "syslog" # exemplechemin: point de départ de la recherche (défaut :.)nom: nom exact ou motif glob
Recherche par motif (glob)
Section intitulée « Recherche par motif (glob) »Trouver des fichiers par extension ou motif.
find <chemin> -name "*.ext" # formulefind . -name "*.log" # exemple*: joker — n'importe quels caractères- toujours entre guillemets, sinon le shell interprète le
*
Filtrer par type
Section intitulée « Filtrer par type »Restreindre aux fichiers, dossiers ou liens.
find <chemin> -type <f|d|l> # formulefind /etc -type d -name "*.d" # exemplef: fichier régulier —d: dossier —l: lien symbolique
Filtrer par taille
Section intitulée « Filtrer par taille »Trouver les gros fichiers ou les fichiers minuscules.
find <chemin> -type f -size <+|->N<c|k|M|G> # formulefind /var/log -type f -size +100M # exemple+/-: plus grand / plus petit que- unités :
coctets,kKo,MMo,GGo
Filtrer par date de modification
Section intitulée « Filtrer par date de modification »Trouver les fichiers récents ou anciens.
find <chemin> -mtime <+|->N # formulefind /tmp -type f -mtime +30 # exemple+N: modifié il y a plus de N jours-N: modifié il y a moins de N jours
Exécuter une commande (-exec)
Section intitulée « Exécuter une commande (-exec) »Lancer une commande pour chaque fichier trouvé.
find <chemin> <tests> -exec <cmd> {} \; # formulefind . -name "*.bak" -exec rm {} \; # exemple{}: remplacé par le nom du fichier\;: termine la commande (échappé)
Exécuter en lot (-exec +)
Section intitulée « Exécuter en lot (-exec +) »Passer plusieurs fichiers à une seule invocation de la commande — bien plus rapide.
find <chemin> <tests> -exec <cmd> {} + # formulefind . -name "*.txt" -exec wc -l {} + # exemple+: agrège les fichiers (commexargs)
Pipeline sécurisé avec xargs -0
Section intitulée « Pipeline sécurisé avec xargs -0 »Traiter sans risque les noms contenant des espaces ou des caractères spéciaux.
find <chemin> <tests> -print0 | xargs -0 <cmd> # formulefind . -name "*.pdf" -print0 | xargs -0 mv -t ~/backup/ # exemple-print0: sépare les résultats par un caractère nulxargs -0: lit ce même séparateur nul
Suppression sécurisée
Section intitulée « Suppression sécurisée »Supprimer des fichiers seulement après avoir vérifié la liste.
find <chemin> <tests> -print # étape 1 : visualiserfind <chemin> <tests> -delete # étape 2 : supprimer- Jamais
-deletesans avoir lancé-printd'abord.
Exclure un dossier (-prune)
Section intitulée « Exclure un dossier (-prune) »Ignorer certains sous-dossiers pendant la recherche.
find <chemin> -path "*/<dossier>" -prune -o <tests> -print # formulefind . -path "./node_modules" -prune -o -name "*.js" -print # exemple-prune: arrête la descente dans le dossier ciblé-o: applique les tests au reste de l'arborescence
Les pièges à éviter
Section intitulée « Les pièges à éviter »Six erreurs reviennent constamment avec find. Certaines sont destructrices — -delete ne pardonne pas.
Recherche sensible à la casse
Section intitulée « Recherche sensible à la casse »find . -name "Report.txt" # ❌ ne trouve pas "report.txt"Symptôme : la recherche ne renvoie rien alors que le fichier existe. Cause : -name distingue les majuscules des minuscules.
find . -iname "report.txt" # ✅ -iname ignore la casseNoms de fichiers avec espaces
Section intitulée « Noms de fichiers avec espaces »find . -name "*.txt" | xargs rm # ❌ casse sur "mon fichier.txt"Symptôme : erreur No such file ou suppression des mauvais fichiers. Cause : xargs découpe sur les espaces.
find . -name "*.txt" -print0 | xargs -0 rm # ✅ séparateur nulOU sans parenthèses
Section intitulée « OU sans parenthèses »find . -name "*.log" -o -name "*.txt" -mtime +7 # ❌ -mtime ne s'applique qu'aux .txtSymptôme : -mtime ne filtre qu'une partie des résultats. Cause : la précédence des opérateurs groupe -mtime avec le second -name.
find . \( -name "*.log" -o -name "*.txt" \) -mtime +7 # ✅ parenthèses échappées-delete sans vérification
Section intitulée « -delete sans vérification »find /var -name "*.tmp" -delete # ❌ exécuté directement, sans contrôleSymptôme : des fichiers importants supprimés par erreur. Cause : un motif trop large appliqué sans prévisualisation.
find /var -name "*.tmp" -print # ✅ vérifier d'abord, puis remplacer -print par -deleteConfusion mtime / ctime / atime
Section intitulée « Confusion mtime / ctime / atime »find . -mtime -1 # ❌ ne reflète pas la « date de création »Symptôme : des fichiers copiés apparaissent comme anciens. Cause : mtime est la date de modification du contenu — Linux n'a pas de « date de création ».
# ✅ -mtime = contenu, -ctime = métadonnées, -atime = dernier accèsfind . -ctime -1Regex au lieu de glob
Section intitulée « Regex au lieu de glob »find . -name ".*\.log$" # ❌ ne renvoie rienSymptôme : aucun résultat. Cause : -name utilise des globs (*, ?), pas des expressions régulières.
find . -regex ".*\.log$" # ✅ -regex pour une vraie regex (ou simplement -name "*.log")Travaux pratiques
Section intitulée « Travaux pratiques »Rien ne remplace la pratique. Créez l'environnement de test ci-dessous, puis déroulez les huit étapes. À la fin, nettoyez avec rm -rf ~/find-lab.
Préparer le terrain
Section intitulée « Préparer le terrain »Ce script crée une arborescence dans ~/find-lab avec des fichiers de tailles, dates et permissions variées — y compris des noms contenant des espaces.
# Créer le labmkdir -p ~/find-lab/{logs,config,data,backup}cd ~/find-lab
# Fichiers logs de différentes taillesdd if=/dev/zero of=logs/app.log bs=1M count=5 2>/dev/nulldd if=/dev/zero of=logs/error.log bs=1K count=100 2>/dev/nulldd if=/dev/zero of=logs/debug.log bs=1M count=20 2>/dev/null
# Fichiers configecho "port=8080" > config/app.confecho "debug=true" > config/debug.conf
# Fichiers avec espaces dans le nomtouch "data/mon fichier.txt"touch "data/rapport 2024.pdf"
# Fichiers avec des dates différentestouch -d "30 days ago" backup/old-backup.tartouch -d "7 days ago" backup/weekly.tartouch backup/daily.tar
# Permissions variéeschmod 777 logs/debug.logchmod 644 config/app.conf
echo "✅ Lab créé dans ~/find-lab"ls -laR ~/find-labLes huit étapes
Section intitulée « Les huit étapes »-
Trouver tous les fichiers
.log. Listez tous les fichiers d'extension.logdu lab.Fenêtre de terminal find ~/find-lab -name "*.log"-nameutilise un motif glob ;*reconnaît n'importe quels caractères. Pour ignorer la casse :find ~/find-lab -iname "*.LOG". -
Filtrer par taille. Trouvez les fichiers de plus de 1 Mo.
Fenêtre de terminal find ~/find-lab -type f -size +1M+1Msignifie « plus de 1 mégaoctet » — le+indique « supérieur à ». -
Fichiers anciens. Trouvez les fichiers modifiés il y a plus de 7 jours.
Fenêtre de terminal find ~/find-lab -type f -mtime +7+7signifie « modifié il y a plus de 7 jours » ;-7serait « moins de 7 jours ». -
Combiner taille ET date. Trouvez les fichiers de plus de 1 Mo modifiés il y a moins de 1 jour.
Fenêtre de terminal find ~/find-lab -type f -size +1M -mtime -1Par défaut, les critères se combinent en ET — inutile d'écrire
-a. -
Fichiers
.logOU.conf. Trouvez les fichiers.logou.conf.Fenêtre de terminal find ~/find-lab \( -name "*.log" -o -name "*.conf" \)-oest le OU ; les parenthèses échappées (\(\)) groupent les conditions. -
Exécuter une commande sur chaque fichier. Affichez la taille lisible de chaque
.log.Fenêtre de terminal find ~/find-lab -name "*.log" -exec ls -lh {} \;{}est remplacé par le nom du fichier ;\;termine la commande. Version plus rapide :-exec ls -lh {} +. -
Gérer les noms avec espaces. Listez en détail les fichiers du dossier
data/.Fenêtre de terminal find ~/find-lab/data -type f -print0 | xargs -0 ls -la-print0etxargs -0utilisent le caractère nul :mon fichier.txtreste un seul argument. -
Supprimer en sécurité. Supprimez les
.tarde plus de 7 jours — visualisez d'abord, supprimez ensuite.Fenêtre de terminal # Étape 1 : visualiserfind ~/find-lab/backup -name "*.tar" -mtime +7 -print# Étape 2 : une fois la liste vérifiéefind ~/find-lab/backup -name "*.tar" -mtime +7 -deleteNe mettez jamais
-deletesans avoir contrôlé la liste avec-print.
Exercices progressifs
Section intitulée « Exercices progressifs »Huit exercices pour valider votre maîtrise. Cherchez d'abord par vous-même, puis dépliez la solution pour vous corriger.
Niveau fondations
Section intitulée « Niveau fondations »Exercice 1 — Trouver les fichiers .conf. Listez les fichiers .conf directement dans /etc, sans descendre dans les sous-dossiers. Indice : -maxdepth 1 limite la profondeur.
Voir la solution
find /etc -maxdepth 1 -name "*.conf"-maxdepth 1 restreint la recherche au dossier de départ, sans récursion.
Exercice 2 — Fichiers vides. Trouvez tous les fichiers vides (0 octet) dans /tmp. Indice : il existe une option dédiée aux fichiers vides.
Voir la solution
find /tmp -type f -empty-empty est plus lisible que -size 0 et fonctionne aussi pour les dossiers vides.
Exercice 3 — Fichiers récents. Trouvez les fichiers de votre dossier personnel modifiés dans les dernières 24 heures. Indice : -mtime avec un nombre négatif.
Voir la solution
find ~ -type f -mtime -1-mtime -1 signifie « modifié il y a moins de 1 jour ».
Niveau composition
Section intitulée « Niveau composition »Exercice 4 — Taille et extension. Trouvez les fichiers .log de plus de 10 Mo dans /var/log. Indice : combinez -name et -size.
Voir la solution
find /var/log -type f -name "*.log" -size +10MLes critères se combinent en ET par défaut — inutile d'écrire -a.
Exercice 5 — OU logique. Trouvez les fichiers .jpg ou .png dans ~/Images. Indice : -o avec des parenthèses échappées.
Voir la solution
find ~/Images -type f \( -name "*.jpg" -o -name "*.png" \)Les parenthèses groupent le OU ; sans elles, la logique serait incorrecte.
Niveau industrialisation
Section intitulée « Niveau industrialisation »Exercice 6 — Exécuter ls -lh sur les résultats. Affichez la taille lisible de chaque fichier de plus de 100 Mo dans /var. Indice : -exec avec ls -lh.
Voir la solution
find /var -type f -size +100M -exec ls -lh {} \;{} est remplacé par chaque fichier trouvé ; \; termine la commande.
Exercice 7 — Pipeline xargs sécurisé. Comptez le nombre total de lignes de tous les fichiers .py d'un projet, même avec des espaces dans les noms. Indice : -print0 puis xargs -0.
Voir la solution
find . -name "*.py" -print0 | xargs -0 wc -l-print0 et xargs -0 gèrent les noms avec espaces sans risque.
Niveau sécurité
Section intitulée « Niveau sécurité »Exercice 8 — Nettoyage sécurisé. Supprimez les fichiers .tmp de plus de 7 jours dans /tmp, en montrant d'abord ce qui sera supprimé. Indice : deux commandes — -print puis -delete.
Voir la solution
# Étape 1 : prévisualiserfind /tmp -name "*.tmp" -mtime +7 -print# Étape 2 : une fois la liste vérifiéefind /tmp -name "*.tmp" -mtime +7 -deleteToujours prévisualiser avec -print avant d'utiliser -delete.
Dépannage
Section intitulée « Dépannage »Quand find ne renvoie pas ce qu'on attend, le problème vient le plus souvent du quoting ou des permissions. Voici comment diagnostiquer.
Méthodes de diagnostic
Section intitulée « Méthodes de diagnostic »# Retirer les filtres un par un pour isoler le problèmefind /chemin
# Ajouter -print explicite pour voir ce qui est traitéfind /chemin -name "*.log" -print
# Vérifier le quoting (le shell peut interpréter * avant find)find /chemin -name "*.log"
# Repérer les dossiers où find n'a pas les droitsfind /chemin 2>&1 | grep -i permissionErreurs fréquentes
Section intitulée « Erreurs fréquentes »| Message d'erreur | Cause probable | Solution |
|---|---|---|
find: '/root': Permission denied | Pas de droit de lecture sur le dossier | Utiliser sudo, ou masquer les erreurs : find /chemin 2>/dev/null |
find: '/chemin': No such file or directory | Le chemin de départ n'existe pas | Vérifier le chemin avec ls, contrôler l'orthographe |
find: missing argument to '-exec' | \; ou + oublié en fin de -exec | Terminer la commande : -exec ls -l {} \; |
Aide-mémoire find
Section intitulée « Aide-mémoire find »Options de parcours
Section intitulée « Options de parcours »| Option | Rôle | Exemple |
|---|---|---|
-maxdepth N | Limite la profondeur de recherche | find . -maxdepth 2 -name "*.txt" |
-mindepth N | Ignore les N premiers niveaux | find . -mindepth 1 -type d |
-L | Suit les liens symboliques | find -L /opt -name "*.conf" |
-xdev | Reste sur le même système de fichiers | find / -xdev -size +100M |
| Filtre | Rôle | Exemple |
|---|---|---|
-name "*.ext" | Nom avec glob (sensible à la casse) | -name "*.log" |
-iname "*.ext" | Nom avec glob (insensible à la casse) | -iname "*.JPG" |
-type f / -type d | Fichiers / dossiers uniquement | -type f |
-path "*pattern*" | Motif sur le chemin complet | -path "*/test/*" |
-size +100M / -size -1k | Plus grand / plus petit que | -size +1G |
-empty | Fichiers ou dossiers vides | -type f -empty |
-mtime +7 / -mtime -1 | Modifié il y a plus / moins de N jours | -mtime +30 |
-newer fichier | Plus récent qu'un fichier de référence | -newer ref.txt |
-perm 644 | Permissions exactes | -perm 755 |
-user bob | Appartient à un utilisateur | -user root |
| Action | Rôle | Exemple |
|---|---|---|
-print | Affiche le chemin (défaut) | -print |
-print0 | Affiche séparé par un caractère nul | -print0 | xargs -0 |
-exec cmd {} \; | Exécute la commande pour chaque fichier | -exec rm {} \; |
-exec cmd {} + | Exécute la commande en lot | -exec ls {} + |
-delete | Supprime les fichiers trouvés | -mtime +30 -delete |
Composition
Section intitulée « Composition »| Opérateur | Rôle | Exemple |
|---|---|---|
-a | ET (implicite entre deux critères) | -name "*.log" -a -size +1M |
-o | OU | -name "*.jpg" -o -name "*.png" |
\( … \) | Groupement de conditions | \( -name "*.jpg" -o -name "*.png" \) |
-prune | Exclut un sous-arbre du parcours | -path "./vendor" -prune |
Checklist de maîtrise
Section intitulée « Checklist de maîtrise »Vous maîtrisez find lorsque vous pouvez cocher chacun de ces points :
- Je sais utiliser
-nameet-iname - Je sais filtrer par
-type(f,d,l) - Je sais utiliser
-sizeavec+/-et les unités - Je sais utiliser
-mtime,-ctime,-atime - Je sais combiner des critères avec
-oet des parenthèses - Je sais utiliser
-exec {} \;et-exec {} + - Je sais sécuriser un pipeline avec
-print0 \| xargs -0 - Je sais sécuriser
-deleteen lançant-printd'abord - Je sais exclure un dossier avec
-prune - Je sais diagnostiquer une recherche qui ne renvoie rien
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Conclusion
Section intitulée « Conclusion »La commande find est un outil essentiel pour quiconque travaille
régulièrement en ligne de commande. Grâce à sa souplesse et à sa richesse
fonctionnelle, elle permet de retrouver, filtrer et manipuler efficacement des
fichiers dans n’importe quelle arborescence. Que ce soit pour une recherche
rapide, un nettoyage automatisé ou un audit de permissions, la maîtrise de
find fait gagner un temps précieux et renforce la qualité de vos scripts et
interventions système.
FAQ - Questions Fréquemment Posées
Section intitulée « FAQ - Questions Fréquemment Posées »Comparaison avec d'autres outils
| Outil | Méthode | Vitesse | Fraîcheur | Usage |
|---|---|---|---|---|
| find | Parcours temps réel | Lente | 100% à jour | Recherche précise avec critères complexes |
| locate | Base de données | Très rapide | Mise à jour quotidienne | Recherche simple par nom |
| grep | Contenu de fichiers | Variable | Temps réel | Recherche dans le contenu |
Syntaxe de base
find [chemin] [critères] [actions]
# Exemples simples
find /home -name "*.log" # Fichiers .log dans /home
find . -type d -name "cache" # Répertoires nommés "cache"
find /var -size +100M # Fichiers > 100 Mo
find /tmp -mtime +7 -delete # Supprimer fichiers > 7 jours
Cas d'usage concrets
- Nettoyage : supprimer fichiers temporaires ou logs anciens
- Audit sécurité : détecter fichiers SUID/SGID ou permissions 777
- Sauvegarde sélective : archiver fichiers modifiés récemment
- Recherche avancée : combiner nom, taille, date, permissions
Comparaison détaillée
| Critère | find | locate |
|---|---|---|
| Méthode | Parcours du système de fichiers en temps réel | Recherche dans une base de données |
| Vitesse | Lent (parcourt physiquement les répertoires) | Très rapide (simple requête SQL) |
| Fraîcheur | 100% à jour (fichiers actuels) | Dépend de la dernière mise à jour (updatedb) |
| Base de données | Aucune | /var/lib/mlocate/mlocate.db |
| Critères | Multiples (nom, taille, date, permissions, etc.) | Nom de fichier uniquement |
| Ressources | CPU et I/O intensifs | Très léger |
| Permissions | Respecte les permissions de l'utilisateur | Affiche tous les fichiers indexés |
Mise à jour de la base locate
# Mettre à jour manuellement la base de données
sudo updatedb
# Vérifier la date de dernière mise à jour
ls -lh /var/lib/mlocate/mlocate.db
# Configuration (quotidienne par défaut via cron)
cat /etc/updatedb.conf
Exemples pratiques
# locate : recherche rapide par nom
locate nginx.conf # Instantané
locate -i readme # Insensible à la casse
# find : recherche précise avec critères
find /etc -name nginx.conf -type f # Plus lent mais précis
find /var/log -name "*.log" -mtime -1 # Fichiers modifiés < 24h
Quand utiliser quoi ?
- locate : recherche rapide de fichiers connus, système stable
- find : recherche précise, fichiers récents, critères multiples, scripts automatisés
find [chemin] [tests] [actions]Structure détaillée
find [chemin_départ] [options] [tests/critères] [actions]
└─ où chercher └─ comment └─ quoi chercher └─ que faire
Composants
| Composant | Description | Exemples |
|---|---|---|
| Chemin | Point de départ de la recherche | /home, ., /var/log |
| Options | Modificateurs de comportement | -maxdepth 2, -mount |
| Tests | Critères de filtrage | -name, -type, -size, -mtime |
| Actions | Opérations sur résultats | -print, -delete, -exec |
Exemples progressifs
# 1. Simple : lister tous les fichiers
find /home/user
# 2. Avec test : fichiers .txt uniquement
find /home/user -name "*.txt"
# 3. Tests multiples : fichiers .txt > 1 Mo
find /home/user -name "*.txt" -size +1M
# 4. Avec action : supprimer fichiers .tmp
find /tmp -name "*.tmp" -delete
# 5. Complexe : logs > 100 Mo modifiés > 7 jours → archiver
find /var/log -name "*.log" -size +100M -mtime +7 -exec gzip {} \;
Opérateurs logiques
# ET implicite (par défaut)
find . -name "*.log" -size +10M # nom ET taille
# OU explicite
find . -name "*.log" -o -name "*.txt" # .log OU .txt
# Négation
find . ! -name "*.git" # tout SAUF .git
find . -not -user root # pas propriétaire root
# Groupement avec parenthèses
find . \( -name "*.log" -o -name "*.txt" \) -size +1M
Diagramme de flux
find /var/log
↓
[Tests] -name "*.log" → Non → Ignorer
↓ Oui
[Tests] -mtime +30 → Non → Ignorer
↓ Oui
[Action] -delete → Supprimer le fichier
Options de recherche
| Option | Sensibilité casse | Portée | Usage |
|---|---|---|---|
-name |
Sensible | Nom du fichier uniquement | Recherche exacte |
-iname |
Insensible | Nom du fichier uniquement | Recherche flexible |
-path |
Sensible | Chemin complet | Filtrage par arborescence |
-ipath |
Insensible | Chemin complet | Filtrage flexible |
-regex |
Sensible (par défaut) | Expression régulière | Recherche complexe |
Wildcards (jokers)
# * : n'importe quels caractères (0 ou plus)
find /var/log -name "*.log" # Tous les .log
find . -name "access*" # access.log, access_2024.log...
# ? : exactement un caractère
find . -name "file?.txt" # file1.txt, fileA.txt (pas file10.txt)
# [] : un caractère parmi une liste
find . -name "file[0-9].txt" # file0.txt à file9.txt
find . -name "[A-Z]*.txt" # Commence par majuscule
# Combinaisons
find . -name "[Dd]ocker*.[jt]son" # Docker.json, dockerfile.json...
Sensibilité à la casse
# -name : sensible à la casse
find . -name "README.md" # Trouve README.md uniquement
# -iname : insensible à la casse
find . -iname "readme.md" # Trouve README.md, readme.MD, ReadMe.md...
Recherche par chemin
# -path : inclure le chemin dans la recherche
find . -path "*/node_modules/*" # Fichiers dans node_modules
find . -path "*/test/*.js" # Fichiers .js dans répertoires test
# Exclure des chemins
find . -path "*/node_modules" -prune -o -name "*.js" -print
Regex (recherche avancée)
# Expression régulière sur le chemin complet
find . -regex ".*/[a-z]+\\.log" # Noms en minuscules + .log
# Regex POSIX étendue (-regextype posix-extended)
find . -regextype posix-extended -regex ".*\\.(jpg|png|gif)$"
Cas pratiques
# Fichiers de configuration
find /etc -name "*.conf"
# Scripts shell
find . -name "*.sh" -o -name "*.bash"
# Fichiers cachés
find ~ -name ".*" -type f
# Fichiers temporaires
find /tmp -name "*~" -o -name "*.tmp" -o -name "*.swp"
Types disponibles
| Type | Description | Exemple |
|---|---|---|
f |
Fichier régulier | Documents, scripts, exécutables |
d |
Répertoire (directory) | Dossiers |
l |
Lien symbolique (symlink) | Raccourcis système |
c |
Périphérique caractère | /dev/null, /dev/tty |
b |
Périphérique bloc | /dev/sda, disques |
p |
Tube nommé (pipe/FIFO) | Communication inter-processus |
s |
Socket | Communication réseau locale |
Exemples courants
# Fichiers réguliers uniquement
find /home -type f -name "*.pdf"
# Répertoires uniquement
find /var -type d -name "cache"
# Liens symboliques
find /usr/bin -type l
# Liens symboliques cassés (dead symlinks)
find /opt -type l ! -exec test -e {} \; -print
Combinaisons utiles
# Fichiers .sh exécutables
find . -type f -name "*.sh" -executable
# Répertoires vides
find /tmp -type d -empty
# Fichiers vides (0 octet)
find /var/log -type f -empty
# Sockets dans /var/run
find /var/run -type s
Cas d'usage spécifiques
# Auditer les liens symboliques dans /etc
find /etc -type l -ls
# Trouver tous les répertoires .git
find ~/projects -type d -name ".git"
# Lister les périphériques bloc
find /dev -type b
# Nettoyer les répertoires vides
find /tmp -type d -empty -delete
Unités de taille
| Suffixe | Unité | Taille réelle |
|---|---|---|
c |
Octets (bytes) | 1 octet |
k |
Kilooctets | 1024 octets |
M |
Mégaoctets | 1024 Ko |
G |
Gigaoctets | 1024 Mo |
T |
Téraoctets | 1024 Go |
| (sans) | Blocs de 512 octets | Ancienne syntaxe |
Opérateurs
# Exactement N unités
find . -size 100k # Exactement 100 Ko
# Plus grand que (+)
find . -size +100M # Fichiers > 100 Mo
# Plus petit que (-)
find /var/log -size -1k # Fichiers < 1 Ko
# Plages (combinaison)
find . -size +10M -size -100M # Entre 10 Mo et 100 Mo
Exemples pratiques
# Logs volumineux (> 100 Mo)
find /var/log -type f -size +100M
# Fichiers vides (0 octet)
find /tmp -type f -size 0
# Cache Docker (images > 1 Go)
find /var/lib/docker -type f -size +1G
# Fichiers suspects (très petits ou très gros)
find /home -type f \( -size -10c -o -size +5G \)
Nettoyage et optimisation
# Supprimer fichiers temporaires > 100 Mo
find /tmp -type f -size +100M -mtime +7 -delete
# Archiver logs > 50 Mo
find /var/log -name "*.log" -size +50M -exec gzip {} \;
# Lister les 10 plus gros fichiers
find /home -type f -size +10M -exec ls -lh {} \; | sort -k5 -hr | head -10
Conversion d'unités
# 100 Mo = 102400 Ko = 104857600 octets
find . -size +100M
find . -size +102400k # Équivalent
find . -size +104857600c # Équivalent
Options de date
| Option | Unité | Signification | Usage |
|---|---|---|---|
-mtime |
Jours | Modification du contenu | Fichiers édités il y a X jours |
-atime |
Jours | Accès en lecture | Fichiers consultés il y a X jours |
-ctime |
Jours | Changement de métadonnées | Permissions/propriétaire modifiés |
-mmin |
Minutes | Modification (minutes) | Fichiers modifiés récemment |
-amin |
Minutes | Accès (minutes) | Fichiers consultés récemment |
-cmin |
Minutes | Changement (minutes) | Métadonnées changées récemment |
-newer |
Référence | Plus récent qu'un fichier | Comparaison relative |
Opérateurs temporels
# +N : plus de N (strictement supérieur)
find /var/log -mtime +30 # Modifiés il y a PLUS de 30 jours
# -N : moins de N (strictement inférieur)
find /tmp -mtime -7 # Modifiés il y a MOINS de 7 jours
# N : exactement N
find . -mtime 0 # Modifiés aujourd'hui (dernières 24h)
Exemples concrets
# Fichiers récents (< 24h)
find /var/log -type f -mtime 0
find /var/log -type f -mmin -60 # Dernière heure
# Fichiers anciens (> 90 jours)
find /backup -type f -mtime +90
# Fichiers non utilisés (jamais accédés depuis 1 an)
find /opt -type f -atime +365
# Fichiers modifiés dans les 7 derniers jours
find /home -type f -mtime -7
Comparaison avec fichier référence
# Fichiers plus récents que reference.txt
find . -newer reference.txt
# Fichiers modifiés après une date précise
touch -t 202601010000 /tmp/marker # 1er janvier 2026
find /data -newer /tmp/marker
Combinaisons utiles
# Logs anciens ET volumineux
find /var/log -name "*.log" -mtime +30 -size +100M
# Fichiers récents d'un utilisateur spécifique
find /home -user alice -mtime -7
# Nettoyage cache (> 7 jours et non accédés)
find ~/.cache -type f -atime +7 -delete
Plages de dates
# Entre 7 et 30 jours
find /tmp -mtime +7 -mtime -30
# Modifiés aujourd'hui ou hier
find /var/log -mtime -2
Notations
| Notation | Exemple | Description |
|---|---|---|
| Octale | 755, 644 |
Permissions en chiffres (rwxr-xr-x) |
| Symbolique | u=rwx,g=rx,o=rx |
Permissions lisibles (user/group/other) |
Modes de correspondance
# Correspondance exacte (sans préfixe)
find . -perm 644 # Exactement rw-r--r--
# Au moins ces permissions (préfixe -)
find . -perm -644 # Au minimum rw-r--r-- (peut avoir +)
# Au moins une permission (préfixe /)
find . -perm /222 # Inscriptible par user OU group OU other
Exemples de sécurité
# Fichiers inscriptibles par tous (DANGER)
find / -type f -perm -002 2>/dev/null
find /var/www -perm /o+w # Symbolique
# Permissions 777 (très permissif)
find /home -type f -perm 0777
# Fichiers SUID (élévation privilèges)
find / -perm -4000 -type f 2>/dev/null
# Fichiers SGID
find / -perm -2000 -type f 2>/dev/null
# SUID + SGID (sticky bit)
find / -perm -6000 -type f 2>/dev/null
Audit des permissions
# Fichiers exécutables non propriétaire root
find /usr/bin -type f -perm -111 ! -user root
# Répertoires sans permission d'exécution
find /var -type d ! -perm -111
# Fichiers lisibles par tous dans /etc
find /etc -type f -perm -004
# Scripts shell non exécutables
find . -name "*.sh" ! -perm -100
Notation symbolique avancée
# Fichiers avec permission user write
find . -perm -u+w
# Fichiers avec permission group read
find . -perm -g+r
# Fichiers avec permission other execute
find /usr/local -perm -o+x
Corriger les permissions
# Retirer permissions d'écriture pour other
find /var/www -type f -perm /o+w -exec chmod o-w {} \;
# Ajouter permission d'exécution aux .sh
find . -name "*.sh" ! -perm -u+x -exec chmod u+x {} \;
# Répertoires : 755, fichiers : 644
find /var/www -type d -exec chmod 755 {} \;
find /var/www -type f -exec chmod 644 {} \;
Bits spéciaux
| Bit | Valeur | Signification |
|---|---|---|
| SUID | 4000 | S'exécute avec les droits du propriétaire |
| SGID | 2000 | S'exécute avec les droits du groupe |
| Sticky | 1000 | Seul le propriétaire peut supprimer (ex: /tmp) |
# Trouver tous les fichiers avec bits spéciaux
find / -perm /7000 -ls 2>/dev/null
Options disponibles
| Option | Type | Description | Exemple |
|---|---|---|---|
-user |
Nom ou UID | Fichiers appartenant à un utilisateur | alice, 1000 |
-group |
Nom ou GID | Fichiers appartenant à un groupe | www-data, 33 |
-uid |
UID uniquement | Recherche par identifiant numérique | 1000 |
-gid |
GID uniquement | Recherche par identifiant de groupe | 1000 |
-nouser |
Orphelin | Fichiers sans propriétaire existant | Audit sécurité |
-nogroup |
Orphelin | Fichiers sans groupe existant | Audit sécurité |
Exemples par nom
# Fichiers d'un utilisateur
find /home -user alice
# Fichiers d'un groupe
find /var/www -group www-data
# Fichiers root uniquement
find /etc -user root -type f
Exemples par ID (UID/GID)
# Recherche par UID
find /home -uid 1000
# Recherche par GID
find /var -gid 33 # www-data
# Utile après suppression utilisateur
find / -uid 1005 2>/dev/null # Utilisateur supprimé
Combinaisons avec permissions
# Fichiers de alice avec permissions 644
find /home/alice -user alice -perm 644
# Fichiers www-data inscriptibles par le groupe
find /var/www -group www-data -perm -g+w
# Fichiers non-root avec SUID (DANGER)
find / ! -user root -perm -4000 2>/dev/null
Audit de sécurité
# Fichiers sans propriétaire (orphelins)
find / -nouser 2>/dev/null
# Fichiers sans groupe
find / -nogroup 2>/dev/null
# Fichiers d'utilisateurs supprimés (UIDs invalides)
find /home -nouser -ls
# Fichiers appartenant à un utilisateur spécifique dans /tmp
find /tmp -user alice -type f
Changer la propriété
# Réassigner les fichiers orphelins
find / -nouser -exec chown root:root {} \;
# Changer le groupe de tous les fichiers d'un projet
find /var/www/projet -exec chgrp www-data {} \;
Syntaxes -exec
| Syntaxe | Exécution | Usage | Performance |
|---|---|---|---|
-exec cmd {} \; |
Une commande par fichier | Actions simples | Lent (fork par fichier) |
-exec cmd {} + |
Commande groupée (batch) | Actions en masse | Rapide (comme xargs) |
Placeholder {}
Le symbole {} est remplacé par le chemin du fichier trouvé.# Syntaxe de base
find /tmp -name "*.tmp" -exec rm {} \;
│ │ │
commande | placeholder | terminateur
Exemples pratiques
# Supprimer des fichiers
find /tmp -name "*.log" -exec rm {} \;
find /tmp -name "*.log" -delete # Équivalent plus rapide
# Changer les permissions
find /var/www -type f -exec chmod 644 {} \;
find /var/www -type d -exec chmod 755 {} \;
# Déplacer des fichiers
find . -name "*.bak" -exec mv {} /backup/ \;
# Copier des fichiers
find /src -name "*.conf" -exec cp {} /dest/ \;
# Archiver des logs
find /var/log -name "*.log" -mtime +30 -exec gzip {} \;
Syntaxe batch {} +
# Exécution groupée (plus rapide)
find /var/log -name "*.log" -exec rm {} +
# Équivaut à : rm file1.log file2.log file3.log...
# Vs syntaxe classique (lent)
find /var/log -name "*.log" -exec rm {} \;
# Équivaut à : rm file1.log && rm file2.log && rm file3.log...
Différence avec xargs
# -exec : intégré à find, gère les espaces
find . -name "*.txt" -exec cat {} \;
# xargs : pipeline, plus flexible
find . -name "*.txt" | xargs cat # ATTENTION aux espaces !
find . -name "*.txt" -print0 | xargs -0 cat # Sécurisé
Commandes complexes
# Exécuter plusieurs commandes
find . -name "*.jpg" -exec sh -c 'convert "$1" "${1%.jpg}.png"' _ {} \;
# Utiliser des variables
find . -type f -exec sh -c 'echo "Fichier: $1, Taille: $(stat -f%z "$1")"' _ {} \;
# Redirection dans -exec
find /var/log -name "*.log" -exec sh -c 'cat "$1" >> /tmp/all.log' _ {} \;
Bonnes pratiques
# 1. Toujours tester avec -print avant -exec
find /data -name "*.tmp" -print # Vérifier les résultats
find /data -name "*.tmp" -exec rm {} \; # Puis exécuter
# 2. Utiliser -ok pour confirmation interactive
find . -name "*.bak" -ok rm {} \; # Demande confirmation
# 3. Préférer {} + pour performances
find /logs -name "*.log" -exec gzip {} + # Batch
# 4. Gérer les erreurs
find / -name "*.conf" -exec cat {} \; 2>/dev/null
Actions intégrées (alternatives)
# -delete : supprimer (plus rapide que -exec rm)
find /tmp -name "*.tmp" -delete
# -print : afficher (par défaut)
find /etc -name "*.conf" -print
# -ls : affichage détaillé (comme ls -l)
find /var -size +100M -ls
Comparaison -exec vs -ok
| Option | Confirmation | Usage | Cas d'usage |
|---|---|---|---|
-exec |
Aucune | Exécution automatique | Scripts, actions sûres |
-ok |
Manuelle (y/n) | Exécution interactive | Suppressions critiques |
Syntaxe
find [chemin] [tests] -ok [commande] {} \;
│ │ │
confirmation fichier terminateur
Exemple interactif
# Supprimer avec confirmation
$ find /tmp -name "*.bak" -ok rm {} \;
< rm ... /tmp/file1.bak > ? y
< rm ... /tmp/file2.bak > ? n
< rm ... /tmp/file3.bak > ? y
# Chaque fichier demande confirmation (y = oui, n = non)
Cas d'usage sécurité
# Suppression de fichiers importants
find /home -name "*.conf" -ok rm {} \;
# Changement de permissions sensibles
find /etc -type f -ok chmod 600 {} \;
# Déplacement de fichiers critiques
find /backup -name "*.sql" -ok mv {} /archive/ \;
Alternative : -okdir
# Exécute la commande depuis le répertoire du fichier
find /var/log -name "*.log" -okdir gzip {} \;
# Plus sécurisé : évite les attaques par lien symbolique
Quand utiliser -ok ?
- Suppressions en masse : vérifier avant de supprimer
- Première exécution d'une commande find complexe
- Environnements sensibles : production, données critiques
- Apprentissage : comprendre ce que fait la commande
Alternative : test avec -print
# Méthode recommandée en production
# 1. Tester avec -print
find /data -name "*.tmp" -print
# 2. Vérifier les résultats
# 3. Exécuter avec -exec (ou -delete)
find /data -name "*.tmp" -delete
Options d'optimisation
| Option | Description | Gain de performance |
|---|---|---|
-maxdepth N |
Limite la profondeur de recherche | ★★★ Très élevé |
-mindepth N |
Ignore les N premiers niveaux | ★★ Modéré |
-prune |
Exclut des répertoires entièrement | ★★★ Très élevé |
-mount (-xdev) |
Ne traverse pas les systèmes de fichiers | ★★ Modéré |
-quit |
Arrête après le premier résultat | ★★★ Maximal |
Limiter la profondeur
# Recherche uniquement dans le répertoire courant (pas de récursion)
find . -maxdepth 1 -name "*.txt"
# 2 niveaux maximum
find /var -maxdepth 2 -name "*.conf"
# Ignorer le répertoire courant (commencer à profondeur 2)
find /home -mindepth 2 -name "*.log"
# Combiner min et max
find /var -mindepth 2 -maxdepth 4 -type d
Exclure des répertoires avec -prune
# Exclure node_modules
find . -path "*/node_modules" -prune -o -name "*.js" -print
# Exclure .git et node_modules
find . \( -path "*/.git" -o -path "*/node_modules" \) -prune -o -type f -print
# Exclure /proc et /sys (système)
find / \( -path /proc -o -path /sys \) -prune -o -name "*.conf" -print
# Exclure plusieurs patterns
find /home \( -name ".cache" -o -name ".npm" -o -name ".local" \) -prune -o -type f -print
Ne pas traverser les montages
# Rester sur le système de fichiers actuel
find / -mount -name "*.log"
find / -xdev -name "*.log" # Alias
# Utile pour éviter /proc, /dev, NFS, etc.
find /home -xdev -type f -size +1G
Arrêt précoce
# Arrêter après le premier résultat
find /etc -name "nginx.conf" -quit
# Trouver un seul exemple
find /var/log -name "*.log" -print -quit
Exemples de performances
# LENT : recherche récursive complète
find /home -name "config.json" # Peut prendre plusieurs minutes
# RAPIDE : limiter la profondeur
find /home -maxdepth 3 -name "config.json" # Quelques secondes
# TRÈS RAPIDE : exclure les gros répertoires
find /home \( -path "*/node_modules" -o -path "*/.cache" \) -prune -o -name "config.json" -print
Benchmarks (exemple)
# Sans optimisation
time find /var -name "*.log"
# real: 2m15s
# Avec -maxdepth
time find /var -maxdepth 3 -name "*.log"
# real: 0m12s (11x plus rapide)
# Avec -prune
time find /var -path "*/docker" -prune -o -name "*.log" -print
# real: 0m08s (17x plus rapide)
Bonnes pratiques
- Toujours limiter la profondeur si possible :
-maxdepth - Exclure les répertoires système :
/proc,/sys,/dev - Exclure les répertoires volumineux :
node_modules,.git,vendor - Utiliser
-xdevpour ne pas traverser les montages - Placer les tests les plus sélectifs en premier (ex:
-nameavant-size) - Utiliser
-quitsi un seul résultat suffit
Template optimisé
# Recherche optimisée standard
find /chemin \
-maxdepth 5 \
-xdev \
\( -path "*/node_modules" -o -path "*/.git" \) -prune -o \
-type f -name "*.ext" -print
Avantages de xargs
| Caractéristique | -exec {} ; | -exec {} + | xargs |
|---|---|---|---|
| Exécutions | Une par fichier | Groupées | Groupées |
| Performance | Très lent | Rapide | Très rapide |
| Flexibilité | Limitée | Limitée | Élevée |
| Gestion espaces | Native | Native | Nécessite -0 |
Problème : espaces et caractères spéciaux
# DANGER : xargs basique casse avec les espaces
find . -name "*.txt" | xargs cat
# Fichier "mon document.txt" sera traité comme 2 fichiers : "mon" et "document.txt"
# SOLUTION : -print0 et -0
find . -name "*.txt" -print0 | xargs -0 cat
# ✅ Fonctionne correctement avec les espaces, tabulations, retours à la ligne
-print0 et -0 (NULL separator)
# find -print0 : séparateur NULL (\0) au lieu de \n
# xargs -0 : lit avec séparateur NULL
find /var/log -name "*.log" -print0 | xargs -0 ls -lh
# Fonctionnement
find . -print # Sortie : file1\nfile 2\nfile3\n
find . -print0 # Sortie : file1\0file 2\0file3\0
Exemples pratiques
# Compter les lignes de tous les fichiers .py
find . -name "*.py" -print0 | xargs -0 wc -l
# Rechercher un motif dans plusieurs fichiers
find /var/log -name "*.log" -print0 | xargs -0 grep "ERROR"
# Copier des fichiers
find /src -name "*.conf" -print0 | xargs -0 -I {} cp {} /dest/
# Supprimer en masse
find /tmp -name "*.tmp" -mtime +7 -print0 | xargs -0 rm
# Archiver
find /data -name "*.csv" -print0 | xargs -0 tar czf archive.tar.gz
Options utiles de xargs
# -I {} : placeholder personnalisé
find . -name "*.txt" | xargs -I {} mv {} {}.bak
# -n N : max N arguments par exécution
find . -type f | xargs -n 10 ls -l # 10 fichiers à la fois
# -P N : exécution parallèle (N processus)
find . -name "*.jpg" -print0 | xargs -0 -P 4 -I {} convert {} {}.png
# -t : afficher les commandes exécutées (debug)
find . -name "*.log" -print0 | xargs -0 -t gzip
Différence de performance
# Test : supprimer 10000 fichiers
# -exec {} \; : ~120 secondes (10000 forks)
time find /tmp/test -name "*.tmp" -exec rm {} \;
# -exec {} + : ~2 secondes (batches)
time find /tmp/test -name "*.tmp" -exec rm {} +
# xargs : ~1.5 secondes (optimal)
time find /tmp/test -name "*.tmp" -print0 | xargs -0 rm
Limites ARG_MAX
# Taille maximale des arguments
getconf ARG_MAX # Exemple : 2097152 (2 Mo)
# xargs divise automatiquement en lots
find / -name "*.log" -print0 | xargs -0 rm
# Si > ARG_MAX, xargs fait plusieurs appels automatiquement
Gestion des erreurs
# Continuer même en cas d'erreur
find . -name "*.txt" -print0 | xargs -0 -r cat
# -r : ne rien faire si entrée vide
# Rediriger les erreurs
find /var -name "*.conf" 2>/dev/null | xargs cat 2>/dev/null
Quand préférer -exec ?
- Commandes complexes avec redirections
- Besoin de confirmation (
-ok) - Compatibilité POSIX stricte
- Sécurité (moins de risque d'injection)
Quand préférer xargs ?
- Performances critiques (milliers de fichiers)
- Traitement parallèle (
-P) - Flexibilité des commandes
- Pipeline avec d'autres outils
Template sécurisé
# Modèle recommandé pour production
find /chemin \
-type f \
-name "pattern" \
-print0 | xargs -0 -r -P 4 commande
│ │ │ │ │
séparateur | | | +-- parallèle (4 processus)
NULL | | +-- ne rien faire si vide
| +-- lire NULL separator
+-- pipeline sécurisé
Checklist production
1. Toujours tester avec -print
# ❌ MAL : exécution directe
find /data -name "*.tmp" -delete
# ✅ BIEN : tester d'abord
find /data -name "*.tmp" -print # Vérifier les résultats
find /data -name "*.tmp" -delete # Puis exécuter
2. Rediriger les erreurs
# Supprimer les erreurs "Permission denied"
find / -name "*.conf" 2>/dev/null
# Rediriger erreurs vers un fichier
find /var -type f -size +1G 2>/var/log/find_errors.log
# Séparer stdout et stderr
find / -name "*.log" > found.txt 2> errors.txt
3. Protéger les motifs avec guillemets
# ❌ MAL : interprétation par le shell
find . -name *.txt # Le shell expand *.txt AVANT find
# ✅ BIEN : guillemets
find . -name "*.txt" # find reçoit le pattern intact
find . -name '*.txt' # Idem
4. Faire des backups avant actions destructives
# Sauvegarder avant suppression
find /data -name "*.old" -exec cp {} /backup/ \; -delete
# Archiver avant modification
tar czf backup_$(date +%Y%m%d).tar.gz /data
find /data -name "*.log" -exec gzip {} \;
5. Utiliser -ok pour confirmation (première fois)
# Confirmation interactive
find /etc -name "*.bak" -ok rm {} \;
# Puis automatiser une fois validé
find /etc -name "*.bak" -delete
Scripts robustes
#!/bin/bash
# Script de nettoyage sécurisé
set -euo pipefail # Arrêt sur erreur
# Variables
TARGET_DIR="/var/log"
MAX_AGE=30
LOG_FILE="/var/log/cleanup.log"
# Fonction de logging
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
# Vérifications préalables
if [[ ! -d "$TARGET_DIR" ]]; then
log "ERREUR: Répertoire $TARGET_DIR introuvable"
exit 1
fi
# Dry-run (mode test)
log "Mode TEST : fichiers qui seraient supprimés"
find "$TARGET_DIR" -name "*.log" -mtime +$MAX_AGE -print | tee -a "$LOG_FILE"
# Confirmation
read -p "Confirmer la suppression ? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
log "Opération annulée"
exit 0
fi
# Exécution
log "Début du nettoyage"
COUNT=$(find "$TARGET_DIR" -name "*.log" -mtime +$MAX_AGE -delete -print | wc -l)
log "$COUNT fichiers supprimés"
Gestion des erreurs
# Continuer même si erreurs
find /var -name "*.log" -exec gzip {} \; 2>/dev/null || true
# Vérifier le code de retour
if ! find /data -name "*.tmp" -delete 2>/dev/null; then
echo "Erreur lors du nettoyage" >&2
exit 1
fi
Logging et audit
# Logger les fichiers traités
find /data -name "*.csv" -exec sh -c 'echo "Traité: $1" >> /var/log/process.log' _ {} \;
# Rapport détaillé
find /backup -type f -mtime -1 -ls > /var/log/backup_report_$(date +%Y%m%d).txt
Optimisations production
# Limiter la charge système avec ionice/nice
nice -n 19 ionice -c3 find /data -name "*.log" -exec gzip {} +
# Exécution en arrière-plan
nohup find / -name "*.tmp" -delete > /var/log/cleanup.log 2>&1 &
# Limitation ressources (cgroups)
systemd-run --scope -p CPUQuota=50% find /data -name "*.old" -delete
Checklist finale
- ✅ Tester avec
-printavant-deleteou-exec - ✅ Rediriger stderr (
2>/dev/nullou vers log) - ✅ Guillemets autour des patterns (
-name "*.txt") - ✅ Backups avant actions destructives
- ✅ Logging des opérations (audit trail)
- ✅ Confirmation pour première exécution (
-ok) - ✅ Optimiser avec
-maxdepth,-prune,-xdev - ✅ Limiter la charge système (
nice,ionice) - ✅ Monitoring des scripts (alertes si échec)
- ✅ Documentation du comportement attendu
Exemples de scripts production
# Nettoyage logs (cron quotidien)
0 2 * * * find /var/log -name "*.log" -mtime +90 -delete 2>>/var/log/cron_errors.log
# Archivage backups (cron hebdomadaire)
0 3 * * 0 find /backup -name "*.sql" -mtime +7 -exec gzip {} \; 2>&1 | logger -t backup
# Audit sécurité (cron quotidien)
0 4 * * * find / -perm -4000 -o -perm -2000 2>/dev/null | mail -s "SUID/SGID Audit" admin@example.com
Types d'audits
| Type | Objectif | Niveau de risque |
|---|---|---|
| SUID/SGID | Détecter élévation de privilèges | 🔴 Critique |
| Permissions 777 | Fichiers trop permissifs | 🔴 Critique |
| World-writable | Répertoires inscriptibles par tous | 🔴 Critique |
| Fichiers volumineux | Gestion de l'espace disque | 🟡 Modéré |
| Fichiers anciens | Nettoyage et archivage | 🟢 Faible |
| Fichiers orphelins | Utilisateurs supprimés | 🟡 Modéré |
1. Audit SUID/SGID (bits spéciaux)
# Fichiers SUID (s'exécutent avec droits propriétaire)
find / -perm -4000 -type f -ls 2>/dev/null
# Fichiers SGID (s'exécutent avec droits groupe)
find / -perm -2000 -type f -ls 2>/dev/null
# SUID ET SGID
find / -perm -6000 -type f -ls 2>/dev/null
# SUID non-root (DANGEREUX)
find / -perm -4000 ! -user root -ls 2>/dev/null
# Rapport détaillé
find / \( -perm -4000 -o -perm -2000 \) -type f -printf "%M %u:%g %p\n" 2>/dev/null > /tmp/suid_audit.txt
2. Audit permissions trop permissives
# Fichiers 777 (tout le monde peut tout faire)
find / -type f -perm 0777 -ls 2>/dev/null
# Répertoires 777
find / -type d -perm 0777 -ls 2>/dev/null
# Fichiers inscriptibles par "other"
find /var/www -type f -perm -002 -ls
# Fichiers lisibles par tous dans /etc
find /etc -type f -perm -004 -ls
# Scripts exécutables world-writable (GRAVE)
find /usr/local/bin -type f -perm -111 -perm -002 -ls
3. Audit fichiers volumineux
# Fichiers > 1 Go
find / -type f -size +1G -exec ls -lh {} \; 2>/dev/null
# Top 20 fichiers les plus gros
find /var -type f -size +100M -exec ls -lh {} \; 2>/dev/null | sort -k5 -hr | head -20
# Logs > 100 Mo
find /var/log -name "*.log" -size +100M -printf "%s %p\n" | sort -nr
# Cache Docker volumineux
find /var/lib/docker -type f -size +500M -ls 2>/dev/null
4. Audit fichiers anciens/non utilisés
# Fichiers non modifiés depuis 1 an
find /home -type f -mtime +365 -ls
# Fichiers jamais accédés depuis 6 mois
find /opt -type f -atime +180 -ls
# Logs de plus de 90 jours
find /var/log -name "*.log" -mtime +90 -exec du -h {} \;
# Backups obsolètes
find /backup -name "*.tar.gz" -mtime +30 -ls
5. Audit répertoires world-writable
# Répertoires inscriptibles par tous (sauf /tmp avec sticky bit)
find / -type d -perm -002 ! -perm -1000 -ls 2>/dev/null
# Répertoires sans sticky bit dans /tmp
find /tmp -type d ! -perm -1000 -ls
6. Audit fichiers orphelins
# Fichiers sans propriétaire (utilisateur supprimé)
find / -nouser -ls 2>/dev/null
# Fichiers sans groupe
find / -nogroup -ls 2>/dev/null
# Combiné
find /home -nouser -o -nogroup 2>/dev/null
Rapports d'audit complets
#!/bin/bash
# Script d'audit sécurité complet
REPORT="/var/log/security_audit_$(date +%Y%m%d).txt"
echo "=== AUDIT SÉCURITÉ $(date) ===" > "$REPORT"
echo "\n### Fichiers SUID/SGID" >> "$REPORT"
find / \( -perm -4000 -o -perm -2000 \) -type f -ls 2>/dev/null >> "$REPORT"
echo "\n### Permissions 777" >> "$REPORT"
find / -type f -perm 0777 -ls 2>/dev/null >> "$REPORT"
echo "\n### Fichiers world-writable" >> "$REPORT"
find / -type f -perm -002 ! -type l -ls 2>/dev/null >> "$REPORT"
echo "\n### Fichiers > 1 Go" >> "$REPORT"
find / -type f -size +1G -ls 2>/dev/null >> "$REPORT"
echo "\n### Fichiers orphelins" >> "$REPORT"
find / \( -nouser -o -nogroup \) -ls 2>/dev/null >> "$REPORT"
# Envoyer le rapport
mail -s "Audit sécurité quotidien" admin@example.com < "$REPORT"
Automatisation (cron)
# /etc/cron.daily/security-audit
#!/bin/bash
# Audit SUID quotidien
find / -perm -4000 -type f -ls 2>/dev/null > /var/log/suid_$(date +%Y%m%d).log
# Alerte si nouveaux fichiers SUID
if ! diff -q /var/log/suid_*.log | tail -2; then
echo "ALERTE: Nouveaux fichiers SUID détectés" | mail -s "Sécurité: SUID" admin@example.com
fi
# Audit permissions 777
find /var/www -type f -perm 0777 -ls 2>/dev/null | \
mail -s "Fichiers 777 dans /var/www" admin@example.com
Tableaux de bord
# Statistiques disque
echo "Fichiers par taille:"
echo " < 1 Mo: $(find /data -type f -size -1M | wc -l)"
echo " 1-10 Mo: $(find /data -type f -size +1M -size -10M | wc -l)"
echo " 10-100 Mo: $(find /data -type f -size +10M -size -100M | wc -l)"
echo " > 100 Mo: $(find /data -type f -size +100M | wc -l)"
# Fichiers par âge
echo "Fichiers par ancienneté:"
echo " < 7 jours: $(find /data -mtime -7 | wc -l)"
echo " 7-30 jours: $(find /data -mtime +7 -mtime -30 | wc -l)"
echo " > 30 jours: $(find /data -mtime +30 | wc -l)"