Les arbres

Prototype


Écrire un programme shell pour afficher les types (fichier ou répertoire) de tous les fichiers du réepertoire courant. Pour éclairer cette question rappelons-nous qu’un répertoire dans le système Unix n’est qu’un fichier contenant sur 2 colonnes une liste de nom de fichiers\footnote{Il n’y a donc pas inclusion des fichiers dans les répertoires comme on en a l’illusion. Les répertoires sont comparables à une table des matières ; les chapitres n’y sont pas inclus.} et le numéro de nœud associé :
 \begin{tabular}{r|lcr|lcr|l} \multicolumn{2}{c}{homedir} & & \multicolumn{2}{c}{dir1} & & \multicolumn{2}{c}{rep2} \\ \cline{1-2} \cline{4-5} \cline{7-8} 132 & .        & \hbox to .3cm {} & 172 & .  & \hbox to .3cm {} & 210 & .\\ 27  & ..       &                 & 132 & .. &                 & 172 & .. \\ 154 & file1    &                 & 201 & fichier1 &           & 240 & data \\ 159 & file2    &                 & 205 & fichier2 &           &     &  \\ 172 & dir1     &                 & 210 & rep2     &           &     &   \\ 198 & dir2     &                 &     &          &           &     &    \\ \end{tabular} {{\sc Fig.} \thesection — {\it Exemple d’arborescence}}
Dans l’exemple ci-dessus (fig. ??), remarquons que le répertoire dir1 contient un nom de fichier désigné par . (point) dont le numéro d’identification (172) est le même que le fichier dir1 du répertoire homedir. Il en va de même pour le répertoire rep2 (210)\footnote{Vous pouvez obtenir des résultats semblables en utilisant la commande ls -i.}. Remarquons aussi que le répertoire dir1 contient un nom de fichier désigné par .. (point, point) dont le numéro (132) est identique à celui du répertoire parent homedir. Respectivement, le nom de fichier .. de rep2(172) correspond au répertoire parent dir1. Ce travail nécessite
  • une boucle pour effectuer la tâche de reconnaissance pour chaque fichier.
  • une variable de boucle.
for FICHIER in *
do
    $FICHIER
done
On a réécrit ls sans option. Pour déterminer le type de fichier, on utilise la commande test ou son abrégée : les crochets.
if [ -d $FICHIER ]
    then echo "$FICHIER repertoire"
    else echo "$FICHIER ordinaire"
fi} 
Remarques :
  • \ast est expansée par le shell\footnote{C’est à dire que le shell remplace \ast par la liste des fichiers du répertoire avant de lancer l’exécution du programme.}. Si le répertoire ne contient pas de fichier, \ast n’est pas expansée,
  • Les fichiers qui commencent par un point ne sont pas pris en compte afin d’éviter leur destruction par un {\tt rm *}.
D’où la version définitive :
for FICHIER in `ls` 
do  
    if [ -d $FICHIER ] 
        echo "$FICHIER repertoire"
        else echo "$FICHIER ordinaire" 
    fi
done

La récursivité : parcours d’une arborescence

Adaptez le programme précédent pour explorer toute une arborescence à partir d’un répertoire passé en paramètre. Le programme que l’on va construire maintenant, sera utilisé ainsi :
 \begin{tabular}{lcll} \$ $\underbrace{\text{\tt prog2}}$ & \hbox to .5cm {} &    $\underbrace{\text{\tt repertoire}}$ & \\ commande & & argument & \\ \multicolumn{1}{c}{\tt \$0} & & \multicolumn{1}{c}{\tt \$1} & \\ \end{tabular}
Pour chaque répertoire rencontré, on rappelle le programme et on poursuit l’exploration par récursivité ; il s’agit d’un parcours préfixé.
$ cat prog2 
\# recuperation de l'argument
REP=$1
for FICHIER in $REP/* 
do
    if [ -d $FICHIER ]
        then echo "Repertoire : $FICHIER"
# fonctionne meme apres un mv
            $0 $FICHIER
        else echo "Fichier    : $FICHIER"
    fi
done
\centerline{{\sc Fig.} \thesection — {\it Script-shell Types de fichiers dans une arborescence}} \addcontentsline{lof}{section}{Script-shell Types de fichiers dans une arborescence}
Les arbres