en pratique

Retour a la page principale


La commande find

Parmi toutes les commandes Unix, find est sans aucun doute l'une des plus puissantes, des moins comprises et des plus effrayantes. Pourtant, une fois maitrisee, elle se revele extremement utile et c'est pourquoi nous allons nous pencher sur elle ce mois-ci. Le but de cet article n'est pas de paraphaser le man, mais d'illustrer a travers quelques exemples le fonctionnement et les possibilites de find.
Le find dont vous disposez sous Linux est celui de GNU qui differe des autres versions sur plusieurs points (notamment il se revele plus souple, comme d'habitude!). Nous allons parler ici de find en general et les exemples marchent sur tous les find (en principe). Parfois, certaines options seront inutiles avec le find de GNU, mais autant les apprendre, ca vous servire le jour ou vous vous retrouverez avec une autre version (genre 10000F HT par utilisateur et par poste, pourquoi pas?)



Comme son nom ne l'indique pas, le but de find n'est pas de chercher un fichier dans l'arborescence (bien qu'il puisse le faire!). Cette commande est en fait beaucoup plus generale et versatile que ca. Ce que fait find, c'est en realite de parcourir une arborescence et appliquer un traitement quelconque a certains fichiers. Il peut donc aussi bien imprimer votre arborescence que rechercher un fichier particulier ou compiler tous les *.c sur votre disque qui appartiennent a l'utilisateur izard, dont la taille fait 342K et dont le chemin d'acces ne contient pas la lettre p.

Les options de la ligne de commande de find forment un veritable langage de programmation qui permet de controler tout ceci. Elles peuvent etre classees dans trois ensembles:

Le man de find contient une liste exhaustive de toutes les commandes, je vous invite donc a le lire. On en verra egalement quelques unes dans nos exemples.



Commencons par le plus simple. Lorsqu'on appelle find, le premier parametre doit etre un nom de repertoire, les parametres suivants sont les commandes sus-citees. Par exemple, la commande -print a pour effet d'afficher le nom du fichier en cours de traitement. Tapez donc:

find . -print

Le repertoire . est le repertoire courant, cette commande a donc pour effet de lister toute l'arborescence depuisle point ou vous vous trouvez. Essayez egalement:

find / -print

et tout le contenu de vos peripheriques mountes defile devant vos yeux!

Maintenant, prenons un exemple pratique. Supposons que vous voulez chercher le fichier XF86Config. Nous allons utiliser pour cela la condition -name suivie d'une expression reguliere qui ordonne a find de ne prendre en compte que les fichiers dont le nom est reconnu par cette expression. Dans notre cas, cela donne:

find / -name "XF86Config" -print

Observez les parantheses autour de l'expression reguliere: elles sont la pour empecher le shell d'evaluer cette expression (il faut toujours se souvenir que sous Unix, les expressions regulieres sont parsees par le shell et non par le
programme appele comme sous DOS, enfin on parlera de ca une autre fois).
Avec cet ordre, find cherchera le fichier dans tous les repertoires mountes. Il est donc utile de connaitre l'option -xdev qui empeche find de chercher ailleurs que dans la partition contenant le repertoire de depart.


Vous connaissez maintenant le principe de find et vous n'avez qu'a consulter le man pour connaitre toutes les commandes, options et conditions. Toutefois, il y a une commande particuliere dont nous allons encore parler: il s'agit de -exec. Cette commande permet de lancer pour chaque fichier un autre programme. C'est tres puissant, mais il faut bien comprendre comment ca marche.
Lorsque find rencontre un -exec, il considere tout ce qui suit comme une ligne de commandes, jusqu'au caractere ;. Exemple:

find / -name ".*rc" -exec echo "J'ai trouve" \;

Deux remarques a propos de cette commande: premierement, j'attire votre attention sur le \ qui precede le ;. En effet, le shell considere le point-virgule comme un separateur de commandes et sans le \, il tenterait d'executer find / -name ".*rc" -exec echo "J'ai trouve" (donc sans le ; fermant -exec) suivi d'une commande vide (celle qui suit le ;).
Deuxiemement, cette commande ne fait qu'afficher "J'ai trouve" un certain nombre de fois: en effet, a chaque fois qu'il rencontre un fichier .*rc, find appelle la commande echo "J'ai trouve".
Pour que tout ceci ait un interet, il faut pouvoir transmettre a la commande lancee par -exec le nom du fichier en cours d'evaluation. find le fait en remplacant dans la commande appelee la chaine de caracteres {} par le nom du fichier. En clair, pour copier tous les fichiers de votre disque commencant par a sous /tmp, tapez par exemple:

find / -name "a*" -exec cp -f -r {} /tmp \; -print

Voila, vous pouvez maintenant parcourir votre disque dans tous les sens et automatiser tout ce que vous voudrez. Avant de nous quitter, je vous suggere d'ouvrir le man de find et regarder toutes ses commandes, puis tenter de resoudre les deux petits exercices suivants:

  1. Ecrivez la commande realisant l'exemple donne en introduction (vous savez, compiler tous les *.c tels que...)
  2. Utilisez find pour effacer tous les fichiers de sauvegarde (ceux qui se terminent par ~ ou %)

Reponses:

  1. find / -name "*.c" -user izard -size 342k -regex "[^p]+" -exec gcc -c {} \;
  2. find / -name "*[~%]" -exec rm -f {} \;