find

Auteur: Ikipou

La commande find est un outil extrêmement puissant pour rechercher des fichiers.

La commande parcourt tous les fichiers à partir d'un emplacement donné, et recherche les fichiers qui correspondent aux critères de recherche. Ces critères peuvent être variés tel que le nom du fichier, ses droits, sa dates d'accès, etc.

Lorsqu'un fichier correspond aux critères, find permet d'exécuter des actions sur celui-ci (comme exécuter une commande). Si aucune action n'est précisé, la commande affiche le chemin vers le fichier.

La commande est d'autant plus puissante qu'elle permet de combiner les critères de recherches à l'aide d'opérateurs logiques. Ces fonctions avancées sont disponible dans la page de manuel et ne sont pas détaillés dans cet article qui ne couvre que les utilisations de base.

Syntaxe

La syntaxe de find est simple: il suffit de préciser le chemin à partir duquel la recherche est effectuée, suivit des paramètres de recherche. Les paramètres comprennent les tests sur les fichiers, les actions, etc.

Si aucun paramètres n'est fournit, find affiche récursivement l'ensemble des dossiers et fichiers du chemin fournit.

Voici par exemple comment lister les fichiers et dossiers de "/etc":

$ find /etc
/etc
/etc/.java
/etc/.java/.systemPrefs
/etc/.java/.systemPrefs/.system.lock
...

Rechercher un fichier par son nom

Un cas courant et de devoir retrouver un fichier par son nom, ou tout les fichiers correspondant à un motif. Pour sélectionner les fichiers en fonction de leur nom, il faut utiliser l'option "-name" suivit du nom de fichier ou du motif à rechercher.

Voici par exemple comment rechercher tout les fichiers et dossiers nommés "passwd" dans le répertoire /etc:

$ find /etc -name 'passwd'
/etc/pam.d/passwd
/etc/passwd

Notez l'utilisation des apostrophes afin d'éviter que l'interpréteur de commande n'étende le motif. Elles sont inutiles dans ce cas ci mais c'est une bonne pratique de toujours les utiliser afin d'éviter l'extension motif.

Pour rechercher un motif, il faut utiliser la même option, et utiliser les mêmes wildcard que pour le shell.

Voici par exemple la recherche de tout les fichiers terminant par ".java" dans le dossier courant:

$ find . -name '*.java'
./java/jdk1.5.0_06/demo/applets/Animator/Animator.java
./java/jdk1.5.0_06/demo/applets/ArcTest/ArcTest.java
./java/jdk1.5.0_06/demo/applets/BarChart/BarChart.java
./java/jdk1.5.0_06/demo/applets/Blink/Blink.java
./java/jdk1.5.0_06/demo/applets/CardTest/CardTest.java
...

Il existe des variantes de l'option -name tel que -iname qui est insensible à la casse et -lname pour les liens symboliques. Ces options sont détaillés dans la page de manuel.

Exécuter une commande

La commande find permet d'effectuer toute sorte d'action avec les fichiers trouvés. Une action très utile est "-exec" qui permet d'exécuter une commande sur les fichiers.

La syntaxe de exec est particulière car il faut pouvoir fournir le nom du fichier trouvé. La syntaxe est : "-exec commande {};". La paire d'accolade est automatiquement remplacée par le nom du fichier, et le point virgule final permet de marquer la fin de la commande.

Cette commande est difficile à utiliser sur certains shell car ceux-ci donnent une signification particulière des caractères comme l'accolade ou le point virgule. Avec Bash, la paire d'accolade sans espace ({}) ne doit pas être protégée, au contraire du point virgule qui doit être echapé à l'aide d'un backslash: \;.

Voici par exemple comment on peut compter le nombre de ligne de chaque fichier de code Python de ce site:

find developpement/django/certif -name '*.py' -exec wc -l {} \;
       1 developpement/django/certif/__init__.py
       0 developpement/django/certif/acronym/__init__.py
      48 developpement/django/certif/acronym/models.py
      82 developpement/django/certif/acronym/tools.py
      13 developpement/django/certif/acronym/urls.py
      42 developpement/django/certif/acronym/views.py
...

Ici la commande find est utilisée avec l'option -name pour ne sélectionner que les fichiers se terminant par ".py" (extension de Python). La commande "wc" (qui compte le nombre de ligne avec -l) est invoquée à l'aide "-exec" sur chacun de ces fichiers.

Il existe d'autres variantes de l'exécution de commande comme l'option -execdir qui exécute la commande à partir du répertoire du fichier. Dans un soucis de concision, ces variantes ne sont pas expliquées ici mais elles sont décrites en détail dans la page de manuel.

Filtrer en fonction des droits

Une option très pratique est -perm qui permet de sélectionner des fichiers en fonctions de leurs droits. Les droits peuvent être donné en forme octale ou littérale.

Voici par exemple comment obtenir la liste de tout les fichiers qui ont le bit setuid valant 1 dans le repertoire /bin:

$ find /bin -perm /5000 -user root
/bin/su
/bin/mount
/bin/umount
/bin/ping
/bin/ping6

Cette option est intéressante pour la sécurité. Les fichiers listés dans la commande précédente sont tous exécuté avec les droits root.

Page de manuel

La commande find est puissante et riche en options. La page de manuel de find est donc de taille conséquente, elle reste néanmoins la source la plus sure pour avoir la documentation des options.

Pour retrouver la syntaxe d'une option connue, il est plus rapide d'utiliser l'aide intégré à la commande à l'aide de find --help.

Heureux qui, dans ses vers, sait d'une voix légère,
Passer du grave au doux, du plaisant au sévère.
-+- Nicolas Boileau, Art Poétique, chant 1er -+-