Commande Linux find : options -name, -type, -size, -mtime et -delete
La commande Linux find parcourt l'arborescence à partir d'un dossier de départ et trouve les fichiers et dossiers qui répondent à des conditions comme le nom, le type, la taille, la date de modification et les permissions. En créant dix fichiers dans un dossier de test d'un serveur AlmaLinux 9 et en l'exécutant avec une condition différente à chaque fois, nous en sommes venus à passer les fichiers trouvés avec -exec à d'autres commandes et, pour supprimer, à vérifier d'abord la liste avec les mêmes conditions avant -delete.
Les chemins du dossier de test et les dates des fichiers dans les encadrés de résultat ont été remplacés par des valeurs d'exemple. Pour la sortie du serveur Debian 12, seul le chemin du dossier personnel est une valeur d'exemple, le reste est tel quel.
1️⃣ Utilisation de la commande Linux find
La forme de base est [find chemin-de-départ conditions]. Sans chemin de départ, find cherche dans le dossier courant (.), et sans condition, il affiche tous les fichiers et dossiers sous le chemin de départ.
Le test a été fait dans /root/work, avec trois dossiers et dix fichiers comme ci-dessous.
find /root/work/root/work
/root/work/docs
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/backup
/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtfind ne trie pas les résultats par nom ; lors de cette exécution, arrivé au dossier docs, il a d'abord affiché tous les fichiers qu'il contient avant de passer à logs.
Si vous enchaînez plusieurs conditions, seuls les fichiers qui les remplissent toutes restent.
-name compare au motif uniquement le nom du fichier, pas le chemin. Entourez le motif de guillemets simples pour que le shell ne développe pas * d'abord et le passe tel quel à find.
find /root/work -name '*.txt'/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txt-name respecte la casse. La recherche des noms commençant par readme n'a trouvé que docs/readme.txt, et -iname a aussi trouvé README.md.
find /root/work -name 'readme*'/root/work/docs/readme.txtfind /root/work -iname 'readme*'/root/work/docs/readme.txt
/root/work/README.mdfind fait partie du paquet findutils. La version lue sur la première ligne de [find --version] était findutils 4.8 sur le serveur AlmaLinux 9.8 et 4.9 sur le serveur Debian 12.
2️⃣ find -type d et -maxdepth
-type f ne garde que les fichiers normaux et -type d que les dossiers.
find /root/work -type d/root/work
/root/work/docs
/root/work/logs
/root/work/backupLe chemin de départ /root/work étant aussi un dossier, il est apparu sur la première ligne. Avec -type f sur le même chemin, les dix fichiers sont apparus.
-maxdepth fixe le nombre de niveaux parcourus sous le chemin de départ. Avec -maxdepth 1, les fichiers de docs et logs sont sortis du résultat, et seuls les cinq fichiers directement sous /root/work sont restés.
find /root/work -maxdepth 1 -type f/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtÀ l'inverse, -mindepth 2 a sauté ce qui se trouve directement sous le chemin de départ et n'a affiché que les cinq fichiers des sous-dossiers.
find /root/work -mindepth 2 -type f/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpLa page man conseille d'écrire les options globales comme -maxdepth juste après le chemin de départ. -maxdepth 1 écrit après -type f a donné les mêmes cinq fichiers, mais dans un terminal une ligne d'avertissement demande de placer les options globales devant (selon la page man).
Pour vérifier seulement le nombre de dossiers ou de fichiers, passez la sortie à wc -l. Le comptage de la sortie de -type d a donné 4, chemin de départ compris.
find /root/work -type d | wc -l4Avec -maxdepth 1, le résultat est aussi 4, car les trois sous-dossiers se trouvent directement sous le chemin de départ.
find /root/work -maxdepth 1 -type d | wc -l4Le comptage des seuls fichiers des sous-dossiers avec -mindepth 2 a donné 5.
find /root/work -mindepth 2 -type f | wc -l53️⃣ Conditions de taille et de temps de la commande find
Un + devant un nombre signifie supérieur à cette valeur, un - inférieur, et sans signe exactement cette valeur. Les unités de -size figurent dans le tableau ci-dessous (selon la page man).
| Unité | Taille | Oui |
|---|---|---|
| c | 1 octet | -size +500c |
| k | 1,024 octets | -size +1k |
| M | 1,048,576 octets | -size +1M |
| G | 1,073,741,824 octets | -size +1G |
| (aucune) | Blocs de 512 octets | -size +2 |
find /root/work -type f -size +1k/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txtLes fichiers de plus de 1k étaient guide.txt avec 5,000 octets, app.log avec 2MB et report.txt avec 1,200 octets.
find /root/work -size +1M/root/work/logs/app.logAvec -size écrit deux fois pour fixer une plage, seuls les deux fichiers de plus de 1k et de moins de 100k sont restés.
find /root/work -type f -size +1k -size -100k/root/work/docs/guide.txt
/root/work/report.txt-size divise la taille par l'unité et arrondit au supérieur avant de comparer. README.md, avec 300 octets, compte donc aussi pour 1k, et -size -1k n'a affiché qu'empty.txt, de taille 0.
find /root/work -type f -size -1k/root/work/empty.txtPour tester les conditions de temps, nous avons réglé la date de modification de README.md, my notes.txt et docs/readme.txt à il y a 3 jours, et celle des deux fichiers .tmp à il y a 10 jours. Chaque fichier conserve trois dates, accès, modification et changement, que vous pouvez consulter avec la commande stat.
-mtime compte le temps écoulé depuis la dernière modification par tranches de 24 heures. -mtime -1 a affiché les cinq fichiers créés dans les 24 heures.
find /root/work -type f -mtime -1/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-mtime +7 n'a affiché que les deux fichiers .tmp réglés à il y a 10 jours. Utilisez cette forme pour vérifier la liste avant de supprimer d'anciens journaux ou fichiers temporaires.
find /root/work -type f -mtime +7/root/work/docs/old.tmp
/root/work/logs/cache.tmp-mmin fait le même calcul en minutes. -mmin -60 a donné les mêmes cinq fichiers que -mtime -1.
find /root/work -type f -mmin -60/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-newer trouve les fichiers modifiés après un fichier de référence. Avec README.md, réglé à il y a 3 jours, comme référence, les cinq fichiers créés ensuite sont apparus.
find /root/work -type f -newer /root/work/README.md/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-empty trouve à la fois les fichiers de taille 0 et les dossiers vides : le dossier vide backup et empty.txt sont apparus.
find /root/work -empty/root/work/backup
/root/work/empty.txt4️⃣ Conditions -perm et -user de find
Avec seulement un nombre après -perm, find cherche les fichiers ayant exactement ces permissions. -perm 644 a écarté run.sh à 755 et my notes.txt à 600, et huit fichiers sont apparus.
find /root/work -type f -perm 644/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/report.txt
/root/work/README.md
/root/work/empty.txtUn - devant le mode cherche les fichiers ayant toutes les permissions indiquées. Seul run.sh avait la permission d'exécution du propriétaire (u+x).
find /root/work -type f -perm -u+x/root/work/run.shUn / devant le mode suffit à trouver un fichier ayant l'une des permissions indiquées. 6000 est la somme de SUID (4000) et SGID (2000) : cette forme sert à contrôler sur un serveur les fichiers qui s'exécutent avec les permissions de leur propriétaire ou groupe.
Le dossier de test n'en contenait aucun : après avoir donné SUID à run.sh, l'exécution a affiché run.sh.
chmod u+s /root/work/run.shfind /root/work -type f -perm /6000/root/work/run.shD'anciennes sources indiquent -perm +6000 au même endroit. Exécuté tel quel, cela s'est terminé par l'erreur [invalid mode].
find /root/work -type f -perm +6000find: invalid mode '+6000'La forme + a été supprimée dans findutils 4.5.12 (selon la page man) : écrivez donc /. Le SUID donné pour le test a été retiré avec chmod u-s.
-user filtre par nom de propriétaire. Tous les fichiers de test appartiennent à root, donc -user root seul ne filtre rien ; en ajoutant -name pour choisir les fichiers .log, seul app.log est resté.
find /root/work -type f -user root -name '*.log'/root/work/logs/app.log-nouser trouve les fichiers dont l'UID de propriétaire ne correspond à aucun compte. Il sert à contrôler les fichiers restés sur un serveur après la suppression d'un compte ; après avoir changé le propriétaire de guide.txt pour l'UID inexistant 1500, guide.txt est apparu.
chown 1500:1500 /root/work/docs/guide.txtfind /root/work -nouser/root/work/docs/guide.txt-nogroup fait le même contrôle sur le groupe propriétaire, et guide.txt, dont le groupe a aussi été changé en 1500, est apparu. Après le test, nous avons rétabli le tout avec chown root:root.
Avec -o entre deux conditions, l'une des deux suffit. Avec une autre condition comme -type f, regroupez entre parenthèses les conditions reliées par -o. Placez une barre oblique inverse devant les parenthèses pour que le shell ne les interprète pas d'abord, et laissez une espace entre parenthèses et conditions.
find /root/work -type f \( -name '*.log' -o -name '*.tmp' \)/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp! inverse la condition qui le suit. La recherche des fichiers autres que .txt en a trouvé cinq.
find /root/work -type f ! -name '*.txt'/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/README.md
/root/work/run.sh5️⃣ Utiliser find -exec
-exec exécute la commande écrite ensuite pour chaque fichier trouvé, le chemin trouvé prenant la place de {}. Le ; en fin de commande s'écrit \; pour que le shell ne le lise pas d'abord comme séparateur de commandes.
find /root/work -name '*.log' -exec ls -l {} \;-rw-r--r-- 1 root root 2097152 Oct 5 14:10 /root/work/logs/app.logSi vous terminez par + au lieu de \;, les chemins trouvés sont regroupés et la commande ne s'exécute qu'une fois. En comparant avec echo, \; a affiché les cinq chemins sur cinq lignes, et + sur une ligne.
find /root/work -name '*.txt' -exec echo {} \;/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txtfind /root/work -name '*.txt' -exec echo {} +/root/work/docs/readme.txt /root/work/docs/guide.txt /root/work/report.txt /root/work/my notes.txt /root/work/empty.txtLes commandes qui acceptent plusieurs chemins, comme ls, se regroupent avec + pour réduire le nombre d'exécutions. Nous avons vérifié la taille des trois fichiers de plus de 1k avec un seul ls -lh.
find /root/work -type f -size +1k -exec ls -lh {} +-rw-r--r-- 1 root root 4.9K Oct 5 14:10 /root/work/docs/guide.txt
-rw-r--r-- 1 root root 2.0M Oct 5 14:10 /root/work/logs/app.log
-rw-r--r-- 1 root root 1.2K Oct 5 14:10 /root/work/report.txt-exec sert aussi à fixer en masse les permissions d'un dossier web, 644 pour les fichiers et 755 pour les dossiers. Avant de lancer, nous avons cherché les fichiers aux valeurs différentes : run.sh et my notes.txt sont apparus.
find /root/work -type f ! -perm 644/root/work/run.sh
/root/work/my notes.txtFichiers et dossiers ont des permissions différentes : lancez donc séparément -type f et -type d. chmod accepte aussi plusieurs chemins, nous avons donc terminé par +.
find /root/work -type f -exec chmod 644 {} +find /root/work -type d -exec chmod 755 {} +Une nouvelle recherche avec la même condition n'a rien trouvé, et le dossier backup, réglé à 700 au préalable, est passé lui aussi à 755.
En revanche, run.sh est aussi passé à 644, et son exécution a donné [Permission denied]. Dans les dossiers contenant des exécutables, redonnez à ces fichiers la permission d'exécution avec chmod +x.
Pour ne modifier que les fichiers des sous-dossiers, ajoutez -mindepth 2. Avec 660, seuls les cinq fichiers de docs et logs ont changé, et nous les avons remis à 644 après vérification.
find /root/work -mindepth 2 -type f -exec chmod 660 {} +find /root/work -type f -perm 660/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpEn reliant find et grep, vous cherchez par contenu de fichier et non par nom. Pour simuler un contrôle de web shell, nous avons créé quatre fichiers PHP dans un dossier séparé /root/site et placé la chaîne [base64_decode] dans html-cache.php et photo.php du dossier upload.
find /root/site -type f/root/site/lib/func.php
/root/site/upload/html-cache.php
/root/site/upload/photo.php
/root/site/index.phpSi vous connaissez le nom du web shell, cherchez avec -name. En ajoutant -maxdepth 2 pour descendre seulement jusqu'au dossier upload, seul html-cache.php est apparu.
find /root/site -maxdepth 2 -type f -name 'html*.php'/root/site/upload/html-cache.phpphoto.php, au nom banal, n'est pas apparu ici. grep -l lancé par -exec n'affiche que les chemins des fichiers contenant la chaîne, et les deux fichiers sont apparus.
find /root/site -name '*.php' -exec grep -l 'base64_decode' {} +/root/site/upload/html-cache.php
/root/site/upload/photo.php[base64_decode] est une fonction présente aussi dans les fichiers du cœur de WordPress : ouvrez donc les fichiers trouvés et vérifiez leur contenu avant de les supprimer.
-print0 place un caractère nul au lieu d'un saut de ligne entre les chemins. Ce caractère est invisible à l'écran, et les chemins sont donc apparus collés sur une ligne.
find /root/work -name '*.txt' -print0/root/work/docs/readme.txt/root/work/docs/guide.txt/root/work/report.txt/root/work/my notes.txt/root/work/empty.txtPour passer à une autre commande des noms avec espaces comme my notes.txt sans les couper, la sortie de -print0 s'utilise avec xargs -0 (selon la page man).
6️⃣ Supprimer des fichiers avec find et options
Avant de supprimer, lancez d'abord les mêmes conditions sans suppression et vérifiez de vos yeux la liste des fichiers à supprimer.
find /root/work -name '*.tmp'/root/work/docs/old.tmp
/root/work/logs/cache.tmp-exec rm {} \; lance rm pour chaque fichier trouvé. Lancé seulement sur le dossier logs, il a supprimé cache.tmp et seul app.log est resté.
find /root/work/logs -name '*.tmp' -exec rm {} \;ls /root/work/logsapp.log-delete fait supprimer directement par find sans lancer rm. L'exécution n'a rien affiché, et une nouvelle recherche avec la même condition n'a plus trouvé de fichier .tmp.
find /root/work -name '*.tmp' -deletefind /root/work -name '*.tmp'-delete doit toujours se placer après les conditions. find évalue la ligne de commande depuis le début comme une seule expression : avec -delete en tête, il tente de tout supprimer sous le chemin de départ avant de regarder les conditions (selon la page man).
🔲 Options de la commande find
📌 Options principales : résultats de cet article
| Option | Rôle | Résultat dans cet article | |
|---|---|---|---|
| -name | Trouve les noms correspondant à un motif (respecte la casse) | '*.txt' donne cinq fichiers ; 'readme*' seulement docs/readme.txt | |
| -iname | Compare les noms sans tenir compte de la casse | 'readme*' donne docs/readme.txt et README.md | |
| -type f, -type d | Ne garde que les fichiers normaux (f) ou les dossiers (d) | -type d donne quatre dossiers avec le chemin de départ ; -type f dix fichiers | |
| -maxdepth | Descend seulement de N niveaux sous le chemin de départ | -maxdepth 1 ne laisse que les cinq fichiers directement sous /root/work | |
| -mindepth | Saute les niveaux au-dessus de N sous le chemin de départ | -mindepth 2 ne donne que les cinq fichiers des sous-dossiers | |
| -size | Cherche par taille (+ plus grand, - plus petit, unités c, k, M, G) | -size +1k donne trois fichiers ; -size -1k seulement empty.txt | |
| -mtime | Compare le temps écoulé depuis la modification du contenu par tranches de 24 heures | -mtime -1 donne cinq fichiers ; -mtime +7 deux fichiers .tmp | |
| -mmin | Compare le temps écoulé depuis la modification en minutes | -mmin -60 donne les mêmes cinq fichiers que -mtime -1 | |
| -ctime | Compare par tranches de 24 heures jusqu'au changement d'informations comme les permissions et le nom | -ctime -1 donne les dix fichiers de test | |
| -newer | Trouve ce qui a été modifié après un fichier de référence | Cinq fichiers avec README.md, réglé à il y a 3 jours, comme référence | |
| -empty | Trouve les fichiers de taille 0 et les dossiers vides | Donne le dossier vide backup et empty.txt | |
| -perm | Cherche par permissions (nombre seul : valeur exacte ; - devant : toutes les permissions indiquées ; / devant : au moins une) | -perm 644 donne huit fichiers, -perm -u+x donne run.sh et -perm /6000 donne run.sh après SUID | |
| -user | Filtre par nom de propriétaire | Avec -name '*.log', donne app.log ; un compte inexistant finit par une erreur | |
| -nouser | Trouve ce dont l'UID de propriétaire n'a pas de compte | Donne guide.txt, avec l'UID changé en 1500 | |
| -nogroup | Trouve ce dont le GID de groupe n'a pas de groupe | Donne guide.txt, avec le GID changé en 1500 | |
| -o | Garde ce qui répond à l'une des deux (entre parenthèses avec d'autres conditions) | En regroupant .log et .tmp, trois fichiers apparaissent | |
| ! | Inverse la condition qui suit | Donne cinq fichiers autres que .txt | |
| -exec | Lance la commande écrite ensuite pour chaque fichier trouvé (chemin à la place de {}) | En terminant par +, un seul echo affiche cinq chemins sur une ligne | |
| -print0 | Place un caractère nul au lieu d'un saut de ligne entre les chemins | Le caractère nul est invisible, les chemins sont collés sur une ligne | |
| -delete | find supprime directement les fichiers trouvés (après les conditions) | Rien d'affiché ; une nouvelle recherche ne trouve plus de fichier .tmp |
📎 Autres options : selon le manuel officiel
| Option | Rôle | |
|---|---|---|
| -L | Suit les liens symboliques et utilise les informations du fichier cible | |
| -path | Compare le chemin entier, pas le nom, à un motif du shell | |
| -regex | Compare le chemin entier à une expression régulière | |
| -iregex | Compare comme -regex, sans tenir compte de la casse | |
| -atime | Compare le temps écoulé depuis le dernier accès par tranches de 24 heures | |
| -cnewer | Trouve ce dont l'état a changé après la modification du fichier de référence | |
| -group | Filtre par nom du groupe propriétaire | |
| -xdev | Ne descend pas dans les dossiers d'autres systèmes de fichiers | |
| -daystart | Calcule les conditions de temps depuis 0 h aujourd'hui au lieu d'il y a 24 heures | |
| -prune | S'il s'agit d'un dossier, n'y descend pas | |
| -quit | Termine aussitôt (-print -quit n'affiche que le premier résultat) | |
| -printf | Affiche selon un format que vous définissez | |
| -ls | Affiche les fichiers trouvés au format ls -dils | |
| -fprint | Enregistre les chemins trouvés dans un fichier indiqué au lieu de l'écran | |
| -ok | Comme -exec, mais demande d'abord confirmation | |
| -execdir | Comme -exec, mais lance la commande dans le dossier du fichier trouvé |
🔲 Simulateur de la commande find
Le simulateur ci-dessous est un serveur virtuel contenant le même dossier de test, où vous pouvez exécuter vous-même des conditions comme -name, -type, -size, -mtime et -perm, ainsi que -exec et -delete.
7️⃣ Erreurs de la commande find
Si vous écrivez un motif sans guillemets, le shell applique les règles des Jokers et le développe d'abord en noms de fichiers du dossier courant. Après être allés dans le dossier docs et avoir écrit *.txt sans guillemets, le shell a transmis les deux noms guide.txt et readme.txt, d'où l'erreur ci-dessous.
cd /root/work/docsfind /root/work -name *.txtfind: paths must precede expression: `readme.txt'
find: possible unquoted pattern after predicate `-name'?Le code de sortie était 1.
Sans \; ni + à la fin de -exec, le message [missing argument to `-exec’] est apparu.
find /root/work -name '*.log' -exec ls -l {}find: missing argument to `-exec'Un chemin de départ inexistant donne [No such file or directory] et se termine avec le code de sortie 1.
find /nonexistent-dir -name xfind: '/nonexistent-dir': No such file or directoryUn nom de compte inexistant dans -user, ou une valeur autre que les lettres prévues comme f et d dans -type, se termine aussitôt par une erreur sans lancer la recherche.
find /root/work -user nosuchuserfind: 'nosuchuser' is not the name of a known userfind /root/work -type xfind: Unknown argument to -type: xAvec un compte normal du serveur Debian 12, nous avons mis à 000 les permissions du dossier lock dans le dossier de test, puis cherché dans ce dossier. lock étant illisible, [Permission denied] est apparu et le code de sortie était 1.
find ~/findtest/home/user/findtest
/home/user/findtest/report.txt
/home/user/findtest/lock
find: '/home/user/findtest/lock': Permission denied
/home/user/findtest/docs
/home/user/findtest/docs/readme.txtPour masquer seulement les lignes d'erreur, ajoutez 2>/dev/null. Le message a disparu, mais le code de sortie est resté 1.
find ~/findtest -name '*.txt' 2>/dev/null/home/user/findtest/report.txt
/home/user/findtest/docs/readme.txt🔢 FAQ & contenus recommandés
Recherche de contenu
Commande grep sous Linux
Un article sur la commande grep, qui cherche du texte dans les fichiers et affiche ces lignes, et sur ses options.
Suppression
Commande rm sous Linux : l'option rm -rf et supprimer sans confirmation
Un article sur les options -r et -f et les demandes de confirmation de la commande rm pour supprimer fichiers et dossiers.
Espace disque
Commande du : vérifier l'espace disque des fichiers
Un article sur le calcul de l'espace disque occupé par les dossiers et fichiers avec la commande du.
ℹ️ Mention d'affiliation
Le contenu de ce site contient des liens d'affiliation. Lorsqu'un visiteur achète un produit ou un service via l'un de ces liens, le site perçoit une commission du vendeur. Le montant payé par l'acheteur(il baisse lors des promotions ↓), lui, n'augmente pas. Les prix, remises et stocks indiqués correspondent à la date de rédaction et peuvent différer ; vérifiez-les donc auprès du vendeur avant d'acheter. Les produits sont choisis et évalués selon nos propres critères, et les commissions n'influencent ni l'ordre de présentation ni le contenu des évaluations.