#!/bin/bash # script rcursif qui parcourt le sous-arbre d'un rpertoire donn en argument # les chemin tant "absolutiss" # il affiche les noms des rpertoires qu'il parcourt, # le nombre de kB occups par ce rpertoire # le nombre de fichiers et de liens symboliques dans le rpertoire # et vrifie l'exitence des cibles des liens symboliques # avec version 'absolue' de la fonction 'absolutiser' qui absolutise aussi des # '../' l'intrieur du chemin relatif function absolutiser { # fonction donnant un chemin absolu "standard" (sans "..") # lorsqu'on lui donne un chemin absolu et un chemin relatif comme arguments local cheminAbsoluDonne=$1 local cheminRelatifDonne=$2 # "local" permet de rendre une variable locale une fonction # standardiser un "/" derrire un nom de rpertoire : # pour le cheminAbsoluDonne : local slash=`echo $cheminAbsoluDonne | sed "s.*/$/"` # si $cheminAbsoluDonne se termine par un "/" remplacer le tout par un "/" # pour pouvoir identifier ce cas plus facilement if [[ $slash != "/" ]] ; then # si ce n'est pas le cas, (donc qu'il n'y a pas de "/" la fin) # ajouter un "/" la fin cheminAbsoluDonne="$cheminAbsoluDonne/" fi # mme chose pour le cheminRelatifDonne, si c'est un rpertoire : if [[ -d $cheminRelatifDonne ]] ; then slash=`echo $cheminRelatifDonne | sed "s.*/$/"` if [[ $slash != "/" ]] ; then cheminRelatifDonne="$cheminRelatifDonne/" fi fi # initialisation des variables de la boucle while local cheminAbsoluRaccourci=$cheminAbsoluDonne local cheminRelatifRaccourci=$cheminRelatifDonne local premier=`echo $cheminRelatifDonne | cut -d'/' -f 1` # le premier rpertoire du cheminRelatifDonne while [[ $premier == ".." ]] ; do # tant que le cheminRelatifRaccourci commence par ".." # on raccourcit le cheminAbsolu et on enlve le ".." du cheminRelatif cheminAbsoluRaccourci=`echo $cheminAbsoluRaccourci | sed "s[^/]*/$"` # enlever le dernier rpertoire cheminRelatifRaccourci=`echo $cheminRelatifRaccourci | sed "s\.\./"` # enlever le premier "../" premier=`echo $cheminRelatifRaccourci | cut -d'/' -f 1` # redfinir le premier rpertoire du cheminRelatif done cheminAbsolu="$cheminAbsoluRaccourci$cheminRelatifRaccourci" # seule variable globale de la fonction, elle sert en obtenir le rsultat # aprs l'avoir excute local contientPointPointSlash=`echo $cheminAbsolu | sed "s.*\.\./.*VRAI"` if [[ $contientPointPointSlash == "VRAI" ]] ; then # si le $cheminAbsolu trouv contient encore un '../' avantPointPointSlash=`echo $cheminAbsolu | sed "s\.\./.*"` apresPointPointSlash=`echo $cheminAbsolu | sed "s.*\.\./"` absolutiser $avantPointPointSlash "../$apresPointPointSlash" # faire un appel rcursif 'absolutiser' en mettant les '..' # au dbut de la partie relative fi } # fin de function absolutiser tab=" " # le caractre TAB pwd=`pwd` if [[ -z $2 ]] ; then # on est dans le premier appel la ligne de commande # pas dans un appel rcursif # absolutiser le rpertoire de base auquel le script est appliqu absolutiser $pwd $1 # excuter la fonction "absolutiser" base=$cheminAbsolu # en utiliser le rsultat echo "Contenu du rpertoire $base" echo "( et ventuellement de ses sous-rpertoires)" echo "( et test d'existance des cibles des liens)" # $base sera transmis en $2 (deuxiemme argument) aux appels rcursifs repertoireActuel=$base else # on est dans un appel rcursif base=$2 repertoireActuel=$1 fi declare -i nombreliens=0 declare -i nombrefichiers=0 # dclarer la variable "nombrefichiers" avec l'option "-i" pour qu'elle soit numrtique # (par dfaut les variables en shell sont des strings) ls=`ls $repertoireActuel` for name in $ls ; do if [[ -L $repertoireActuel$name ]] ; then # si c'est un lien logique : nombreliens=$nombreliens+1 # incrmenter la variable numrique "nombreliens" # et tester l'existence de la cible du lien : ll=`ls -l $repertoireActuel$name` cible=`echo $ll | cut -d' ' -f 11` # extraire la cible du lien # normaliser un chemin absolu : devant_premier_slash=`echo $cible | cut -d'/' -f 1` # les caractres devant le premier slash du chemin de la cible if [[ -z $devant_premier_slash ]] ; then # s'il n'y en a pas # la cible est dj donne en chemin absolu cheminAbsoluCible=$cible else absolutiser $repertoireActuel $cible cheminAbsoluCible=$cheminAbsolu fi echo echo la cible $cheminAbsoluCible echo du lien $repertoireActuel$name if [[ -e $cheminAbsoluCible ]] ; then # si la cible du lien existe : echo "$tab existe" else echo "$tab n'EXISTE PAS" fi elif [[ -f $repertoireActuel$name ]] ; then nombrefichiers=$nombrefichiers+1 # incrmenter la variable numrique "nombrefichiers" fi if [[ -d $repertoireActuel$name ]] ; then # si c'est un rpertoire, stocker son nom dans la variable "sousrepertoires" # pour les appels rcursifs if [[ -z $sousrepertoires ]] ; then sousrepertoires="$repertoireActuel$name/" else sousrepertoires="$sousrepertoires $repertoireActuel$name/" # avec des espaces comme sparateurs fi fi done durep=`du -s $repertoireActuel` # du -s donne le nombre de kB total dans le rpertoire courant du=`echo $durep | cut -d' ' -f 1` # extraire le nombre de kB echo "$tab$du kB$tab$nombreliens liens$tab$nombrefichiers fichiers" # les appels rcursifs : for rep in $sousrepertoires ; do echo echo -n "sous-rpertoire : $rep" echo # "-n" dit "echo" de ne pas passer la ligne $0 $rep $base # $0 est le nom du script, il est donc appel (rcursivement) # avec comme 1 paramtre le rpertoire qui vient d'tre trouv # le 2 paramtre, "$base", sert la fois inhiber l'affichage explicatif # et transmettre le rpertoire de base aux appels rcursifs done