All pastes #25900 Raw Edit

ScriptBash_ParcoursRecursif_d_Arbre_avec_fonction_d_absolutisation_des_chemins_en_parametre

public text v1 · immutable
#25900 ·published 2005-10-18 22:40 UTC
rendered paste body
#!/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