La commande find ou la puissance de la recherche

From Deimos.fr / Bloc Notes Informatique
Jump to: navigation, search

1 Introduction

La commande find fait partie des commandes avancées les plus efficaces dans l’administration d’un système — elle nécessite les privilèges de l’administrateur.

La commande find est un outil extrêmement puissant, doté d’une cinquantaine d’options, autorisant des recherches définies selon des critères très fins : sur fichiers, répertoires, liens symboliques... à partir du nom (en tenant compte de la casse ou non), selon le propriétaire, la taille, la date, etc, dans un unique système de fichiers ou plus ! Il faut ajouter que ses options se définissent selon deux catégories : sélection et exécution. On mesure alors toute l’étendue de la puissance de cette commande.

La syntaxe de la commande find n’est malheureusement pas des plus courantes. Quelques essais sauront vous convaincre, si ce n’est déjà le cas, de l’adopter au plus vite.

Pour l’anedocte, c’est grâce à cette commande redoutable que j’ai retrouvé, sur mon disque externe, un fichier égaré qui me faisait cruellement défaut depuis plusieurs années :

find /media/IOMEGA_HDD -print0 | xargs --null grep chaplin

Comme le montre la ligne ci-dessus, la commande find s’associe à merveille avec la commande xargs. Par les ressources conjuguées des dites commandes, il s’agissait donc de rechercher dans l’arborescence de mon disque tous les fichiers contenant le mot "chaplin"... find a su retrouver la trace de mon vieux fichier inséré dans un fichier de sauvegarde datant de 2004 ! Chapeau l’artiste !

2 La preuve par l’exemple

Au-delà de l’ergonomie indéniable des outils graphiques, ce qui doit faire la différence est avant tout l’efficacité et la rapidité du résultat. Alors, mettons à l’épreuve les commandes locate, find et l’outil graphique Beagle Search.

Pour cet exemple de recherche, compliquons quelque peu la tâche de nos compétiteurs. La machine de test comprend plusieurs disques durs donc plusieurs partitions, plusieurs systèmes de fichiers, plusieurs OS (Libres only... cela va de soi !). Certaines partitions ne sont dédiées qu’au stockage pur et dur et c’est bien entendu sur ces partitions que la recherche devra faire ses preuves.

2.1 locate et Beagle

Avec une syntaxe élémentaire, le résultat de la commande locate ne correspond absolument pas à celui escompté. Pour obtenir satisfaction, il m’aurait fallu créer mon propre index et très certainement préciser davantage les critères de recherche (chemin, type de fichier, etc.). Mais restons simples.

locate artemis* /usr/share/app-install/icons/_usr_share_pixmaps_artemis.xpm
/usr/share/app-install/desktop/artemis.desktop

En mode graphique, Beagle ne fait pas bien mieux : un seul résultat pour un fichier de plein texte qui n’a absolument rien à voir avec l’objet recherché !

2.2 La commande find... seul et unique vainqueur !

Voici la commande find en action dans une syntaxe basique, histoire de ne pas trop désavantager ses adversaires :

sudo find / -name artemis* -print
[sudo] password for zarer :
/media/disk/documents_pro/2007_2008/lectures/artemis_fowl.odt
/usr/share/app-install/desktop/artemis.desktop

Bingo ! au premier coup d’essai ! Waoooooo ! Pour ma part, il ne m’en faut pas plus pour me convaincre : l’objet recherché est trouvé rapidement, au travers de différents systèmes de fichiers, sans entrer nombre d’options obscures. Remarquable.

En ajoutant une seule option, le propriétaire, le résultat aurait été immanquable :

sudo find / -name artemis* -user zarer -print
[sudo] password for zarer :
/media/disk/documents_pro/2007_2008/lectures/artemis_fowl.odt

gnome-search-tool : find, locate et grep conjuguées !

L’application Recherche de fichiers est la seule, à ma connaissance (disponible immédiatement à l’utilisateur fraîchement débarqué sous Linux avec le bureau Gnome), à pouvoir rivaliser avec find. La raison :

La Recherche de fichiers exploite les commandes UNIX find, grep et locate. Par défaut, lors d’une recherche élémentaire, la Recherche de fichiers utilise d’abord la commande locate, et dans un deuxième temps la commande find, plus lente, mais plus efficace.

Ben voui voui voui ! Y a du find là-d’ssous !

3 Présentation de la commande find

Vous l’aurez compris, cette commande est à ranger parmi les "grands classiques" pour l’administration : find est un outil de base, que cela soit en mode ligne de commandes ou dans les scripts shells.

La commande find recherche des objets (fichiers, répertoires, liens, etc.) dans l’arborescence qui débute au répertoire donné en argument, selon des critères définis, et exécute une action sur cet objet. Le critère de sélection le plus utilisé est le nom de l’objet (fichier, répertoire, ...) et l’action la plus fréquente l’affichage du chemin d’accès à l’objet recherché.

Sa syntaxe générale est la suivante :

find /répertoire_de_recherche -option1 -option2 ...

Voici quelques exemples simples de recherche dans tout ou partie du (ou des) système(s) de fichiers :

4 Exemple 1

Dans ce premier exemple, la commande doit chercher un fichier spécifique nommé mon_premier_fichier à partir du répertoire racine (voir le schéma de l’arborescence UNIX) et afficher le résultat à l’écran :

find / -type f -name mon_premier_fichier -print

5 Exemple 2

Les utilisateurs même les mieux ordonnés savent combien il est parfois difficile de se souvenir du nom exact que l’on a donné à tel ou tel fichier. La commande find autorise elle aussi l’utilisation des caractères jokers ou de substitution :

find / -type f -name *fichier -print

Dans un nom de fichier (ou de répertoire) les caractères jokers ou caractères de substitution jouent un rôle particulier pour l’interpréteur de commandes : ils remplacent un nombre variable de caractères selon le caractère joker employé.

5.1 L’astérique (*)

L’étoile ou (ou astérisque) remplace un nombre quelconque de caractères (y compris aucun). Elle peut être placée n’importe où dans le nom. On se sert souvent de ce caractère pour lister des fichiers sur la base d’une partie du nom.

5.2 Le point d’interrogation ( ?)

Le point d’interrogation ne remplace qu’un caractère et un seul. Il peut être placé n’importe où dans le nom du fichier (répertoire), comme dans les exemples ci-dessous pour la recherche d’un fichier nommé fichier1 ou fichier10 :

find / -type f -name fichier? -print
find / -type f -name fichier?? -print

5.3 Les crochets ([])

Les crochets sont identiques au point d’interrogation seulement la substitution ne s’effectue qu’avec l’un des caractères présentés entre crochets : [abc], [0-9], [!abc] pour un caractère différent de a, b et c, [!0-5], ...

5.4 Exemple 3

Dans ce troisième exemple, la commande doit lister tous les répertoires contenus dans mon répertoire personnel et afficher le résultat à l’écran :

find /home/zarer -type d -print

Quelques options utiles pour recherche avancée

Les options de la commande find se partage en deux catégories : sélection et exécution.

5.4.1 Options pour critères de sélection

Les critères de sélection sont très nombreux et s’appliquent sur le type (fichier, répertoire, ...) et les attributs (propriétaire, groupe, permissions, date de création ou de modification, taille, ...) des objets de la recherche. Contentons-nous d’en présenter quelques-uns (voir la page du manuel de la commande find) :

  • name : effectue une recherche en fonction du nom (sans les répertoires du chemin d’accès). Si le nom défini contient des caractères jokers, il est préférable de l’encadrer de guillemets ou d’apostrophes.
  • iname : identique à -name mais sans différencier les majuscules et les minuscules.
find / -iname "*fichier*" -print
  • type : Cette option précise le type de l’objet recherché. Elle doit être suivie par une lettre qui le définit. Par exemple : d = répertoire, f = fichier régulier ou "normal", l = lien symbolique.
find / -type f -iname "artemis*" -print

L’exemple ci-dessous recherche depuis le répertoire racine tous les fichiers avec l’extension .odt et les affiche :

find / -type f -iname "*.odt" -print
  • user : Fichier appartenant à l’utilisateur indiqué. Extrêmement pratique pour l’administrateur d’un ou plusieurs postes multi-utilisateurs.
  • group : Fichier appartenant au groupe indiqué.
  • mount : La recherche est limitée à un unique système de fichiers ; elle ne doit pas s’effectuer sur les répertoires situés sur d’autres systèmes de fichiers. Il s’agit d’une alternative à l’option -xdev, assurant la compatibilité avec d’anciennes versions de find.

Attention ! Un certain ordre s’impose ! Les options sont dites "positionnelles". Leur contrôle est effectué dans l’ordre de la ligne de commande. À défaut, vous risquez d’obtenir un message du genre :

find : AVERTISSEMENT : vous avez spécifié l’option -mount après un argument qui n’est pas une option -type mais les options sont positionnelles (-mount affecte les tests spécifiés avant aussi bien qu’après)

On conçoit aisément que l’option limitant la recherche au seul système de fichiers soit placée avant le nom du fichier (ou répertoire) recherché et, qu’une fois localisé, il faille ensuite afficher le chemin de l’objet :

find / -mount -type f -iname "*.pdf" -user zarer -print

5.5 Options pour critères d’exécution

Une fois spécifiés les critères de recherche, il est possible de demander à la commande find différentes opérations sur les objets trouvés. La principale opération est tout bonnement d’afficher le résultat de la recherche (le chemin d’accès à l’objet). Encore une fois, les options sont là aussi nombreuses. Reportez-vous à la page du manuel de la commande find pour en connaître le détail.

Les critères de sélection s’appliquent sur le type (fichier, répertoire, ...) et les attributs des objets de la recherche. Contentons-nous d’en présenter quelques-uns :

  • print : Affiche le résultat de la recherche sous la forme d’une liste de chemins d’accès aux objets (fichiers, répertoires...) répondant aux critères de sélection. C’est l’utilisation la plus courante de la commande find.
  • exec commande ; : Exécute la commande. Tous les arguments de find sont considérés comme des arguments pour la ligne de commande, jusqu’à ce qu’on rencontre un " ;". La chaîne "{}" est remplacée par le nom du fichier en cours de traitement, et ceci dans toutes ses occurrences. Ces deux chaînes peuvent avoir besoin d’être protégées du développement de la ligne de commande par le shell, en utilisant le caractère d’échappement ("\") ou une protection par des apostrophes. La commande est exécutée depuis le répertoire de départ.

Le résultat de la recherche peut ainsi servir à d’autres commandes (destruction, sauvegarde, affiche page par page, etc.), comme dans l’exemple de syntaxe de la ligne ci-dessous qui enchaîne la commande rm qui détruira sans demande de confirmation le résultat de la recherche :

find /home -iname mon_fichier_essai -exec rm -f {} \ ;

Si vous avez des craintes ou des doutes lors de l’exécution d’une commande à risque il est dans ce cas préférable d’utiliser l’option suivante :

  • ok commande ; : Cette option est identique à -exec mais interroge d’abord l’utilisateur. Si la réponse ne commence pas par "y" ou "Y", la commande ne sera pas exécutée :
find /home -iname mon_fichier_essai -ok rm -f {} \ ;
< rm ... /home/zarer/Desktop/mon_fichier_essai > ?
  • Il y a une solution encore plus adaptée pour le cas ou vous avez un très grands nombre de fichiers. Cette solution a l'avantage d'être plus optimisée :
find / -name mesfichiers -print0 | xargs -0 rm -f

Le 0 permet de s'affranchir des problèmes d'espaces et retours chariots.

  • Si jamais on souhaite rechercher par exemple des fichiers étant plus vieux que 7 jours :
find . -type f -mtime +7 -exec ls -l {} \;
  • Et si nous nous souhaitons les compresser :
find /path/to/files -type f -mtime +7 | grep -v \.gz | xargs gzip
  • Maintenant, si l'on souhaites recopier des fichiers en respectant une arborescence :
Command find
find / -name "lshell*" | cpio -pduvm .

5.6 Recherche avec plusieurs critères

Quand plusieurs options sont utilisées simultanément, tous les critères sont vérifiés. Entre chacune des options, la commande find use d’un opérateur logique implicite : "Et".

Il est possible de modifier cette règle, en appliquant des opérateurs explicites. Ces opérateurs sont rarement employés mais il peut être intéressant de les connaître pour, par exemple, regrouper plusieurs noms. La syntaxe de la ligne ci-dessous permet de rechercher un objet dont le nom contient deux expressions :

find / \( -iname *image* -a -iname *chaplin* \) -print

5.6.1 Les opérateurs logiques sont présentés dans l’ordre de priorité décroissante

  • \( expression \) : Les parenthèses forcent la priorité. Comme en algèbre, ce qui se trouve entre les parenthèses doit être évalué avant toute autre opération.
  •  ! expression ou -not expression : Vrai si l’expression est fausse. Consiste tout simplement à prendre l’expression comme fausse. On peut par exemple rechercher un fichier qui n’appartient pas à tel ou tel utilisateur.
  • expression1 expression2 : ET (implicite). L’expression2 ne sera pas évaluée si l’expression1 est fausse.
  • expression1 -a expression2 ou expression1 -and expression2 : Comme expression1 expression2. Le -a est donc optionnel.
  • expression1 -o expression2 ou expression1 -or expression2 : OU. L’expression2 n’est pas évaluée si l’expression1 est vraie.
  • expression1 , expression2 : Liste. Les expressions seront toujours évaluées toutes les deux. La valeur de l’expression1 est ignorée ; la valeur de la liste est celle de l’expression2.

Bonne recherche !