#!/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