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 avez une bonne comprendre de la commande find, voici des
modèles courants pour des recherches et traitements fréquents.
Ces recettes couvrent les cas d'usage les plus fréquents. Cliquez sur un pattern pour voir la formule complète et un exemple prêt à copier.
Recherche par nom exact Base Trouver un fichier quand on connaît son nom précis.
find /var/log -name "syslog"
find <chemin> -name "<nom>" find /var/log -name "syslog" -
chemin— Point de départ de la recherche -
nom— Nom exact ou pattern glob
Recherche par pattern (glob) Base Trouver des fichiers par extension ou motif.
find . -name "*.log"
find <chemin> -name "*.ext" find . -name "*.log" -
ext— Extension recherchée -
*— Wildcard : n'importe quels caractères
Filtrer par type Base Restreindre aux fichiers, dossiers ou liens.
find /etc -type d -name "*.d"
find <chemin> -type <f|d|l> find /etc -type d -name "*.d" -
f— Fichier régulier -
d— Dossier -
l— Lien symbolique
Filtrer par taille Base Trouver les gros fichiers ou les fichiers vides.
find /var/log -type f -size +100M
find <chemin> -type f -size <+|->N<c|k|M|G> find /var/log -type f -size +100M -
+/-— + = plus grand, - = plus petit -
N— Nombre -
unité— c=octets, k=Ko, M=Mo, G=Go
Filtrer par date de modification Base Trouver les fichiers récents ou anciens.
find /tmp -type f -mtime +30
find <chemin> -mtime <+|->N find /tmp -type f -mtime +30 -
+N— Modifié il y a plus de N jours -
-N— Modifié il y a moins de N jours -
N— Modifié il y a exactement N jours
Exécuter une commande (-exec) Inter. Lancer une commande pour chaque fichier trouvé.
find . -name "*.bak" -exec rm {} \;
find <chemin> <tests> -exec <cmd> {} \; find . -name "*.bak" -exec rm {} \; -
{}— Placeholder pour le nom du fichier -
\;— Fin de la commande (échappé)
Exécuter en batch (-exec +) Inter. Passer plusieurs fichiers à une seule commande.
find . -name "*.txt" -exec wc -l {} +
find <chemin> <tests> -exec <cmd> {} + find . -name "*.txt" -exec wc -l {} + -
+— Agrège les fichiers (comme xargs)
Pipeline sécurisé avec xargs -0 Inter. Gérer les noms avec espaces et caractères spéciaux.
find . -name "*.pdf" -print0 | xargs -0 mv -t ~/backup/
find <chemin> <tests> -print0 | xargs -0 <cmd> find . -name "*.pdf" -print0 | xargs -0 mv -t ~/backup/ -
-print0— Sépare par NUL au lieu de newline -
-0— xargs lit le format NUL
Suppression sécurisée Avancé Supprimer des fichiers après validation.
find /tmp -type f -mtime +30 -delete
find <chemin> <tests> -print # puis -delete find /tmp -type f -mtime +30 -delete -
-print— Étape 1 : visualiser -
-delete— Étape 2 : supprimer
Exclure un dossier (-prune) Avancé Ignorer certains sous-dossiers de la recherche.
find . -path "./node_modules" -prune -o -name "*.js" -print
find <chemin> -path "*/<dossier>" -prune -o <tests> -print find . -path "./node_modules" -prune -o -name "*.js" -print -
-path— Pattern sur le chemin complet -
-prune— Arrête la descente dans ce dossier -
-o— OU : applique les tests aux autres
Aucune recette ne correspond à votre recherche.
Les Pièges à éviter
Section intitulée « Les Pièges à éviter »Ces erreurs courantes peuvent faire perdre du temps ou causer des dégâts. Les pièges les plus critiques sont affichés en premier.
Noms de fichiers avec espaces find . -name "*.txt" | xargs rm casse sur "mon fichier.txt"
Danger
find . -name "*.txt" | xargs rm casse sur "mon fichier.txt"
find . -name "*.txt" -print0 | xargs -0 rm -delete sans vérification find /var -name "*.tmp" -delete exécuté directement
Danger
find /var -name "*.tmp" -delete exécuté directement
find /var -name "*.tmp" -print # vérifier, puis -delete OU sans parenthèses find . -name "*.log" -o -name "*.txt" -mtime +7
Attention
find . -name "*.log" -o -name "*.txt" -mtime +7
find . \( -name "*.log" -o -name "*.txt" \) -mtime +7 Recherche sensible à la casse find -name "Report.txt" ne trouve pas "report.txt"
Info
find -name "Report.txt" ne trouve pas "report.txt"
find . -iname "report.txt" Confusion mtime/ctime/atime Utiliser -mtime pour trouver des fichiers "créés" récemment
Info
Utiliser -mtime pour trouver des fichiers "créés" récemment
Regex au lieu de glob find . -name ".*\.log$" ne fonctionne pas
Info
find . -name ".*\.log$" ne fonctionne pas
find . -regex ".*\.log$" # ou simplement -name "*.log" Cheatsheet
Section intitulée « Cheatsheet » 📋
Cheatsheet find
📝 Syntaxe :
find [chemin] [filtres] [actions] Format général de la commande 🚀 Commandes types :
find /var/log -name "syslog" find . -name "*.log" find /etc -type d -name "*.d" find /var/log -type f -size +100M find /tmp -type f -mtime +30 ⚙️ Options
-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 |
🔍 Filtres
-name "*.ext" | Nom avec glob (sensible casse) | -name "*.log" |
-iname "*.ext" | Nom avec glob (insensible casse) | -iname "*.JPG" |
-type f | Fichiers uniquement | -type f |
-type d | Dossiers uniquement | -type d |
-path "*pattern*" | Pattern sur le chemin complet | -path "*/test/*" |
📅 Temps
-mtime +7 | Modifié il y a + de 7 jours | -mtime +30 |
-mtime -1 | Modifié il y a - de 1 jour | -mtime -7 |
-newer fichier | Plus récent que fichier | -newer ref.txt |
📏 Tailles
-size +100M | Plus grand que 100 Mo | -size +1G |
-size -1k | Plus petit que 1 Ko | -size -100c |
-empty | Fichiers/dossiers vides | -type f -empty |
🔐 Permissions
-perm 644 | Permissions exactes | -perm 755 |
-perm -u+x | Au moins exécutable user | -perm -g+w |
-user bob | Appartient à bob | -user root |
⚡ Actions
-print | Affiche (défaut) | -print |
-print0 | Affiche séparé par NUL | -print0 | xargs -0 |
-exec cmd {} \; | Exécute cmd pour chaque | -exec rm {} \; |
-exec cmd {} + | Exécute cmd en batch | -exec ls {} + |
-delete | Supprime | -mtime +30 -delete |
🔗 Composition
-a | ET (implicite) | -name "*.log" -a -size +1M |
-o | OU | -name "*.jpg" -o -name "*.png" |
\( ... \) | Groupement | \( -name "*.jpg" -o -name "*.png" \) |
-prune | Exclure un sous-arbre | -path "./vendor" -prune |
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" [email protected]
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" [email protected] < "$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" [email protected]
fi
# Audit permissions 777
find /var/www -type f -perm 0777 -ls 2>/dev/null | \
mail -s "Fichiers 777 dans /var/www" [email protected]
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)"