Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 29/06/2009, à 22:51

BorX

Script Shell qui transforme les fichiers doublons en liens durs

Salut,

Ce script cherche les doublons dans les répertoires qu'on lui spécifie, et les remplace par des liens durs (hard links).

Les liens durs, c'est quoi
Un hardlink, c'est par exemple plusieurs fichiers qui pointent au même endroit du disque dur. Modifier l'un modifie tous les autres. Supprimer l'un ne change rien aux autres (contrairement aux liens symboliques avec lesquels la suppression de la cible rend le lien inutilisable).
Tous les fichiers liés pointent sur le même i-noeud de la partition, ils n'occupent donc que la place d'un seul de ces fichiers sur le disque. Chaque fichier reste cependant un fichier réél.
Attention : Lier des fichiers en dur ne peut être effectué que sur une même partition.

Ce script utilise fdupes qui permet de rechercher les doublons, mais ne permet pas de les lier ensuite.

Ainsi, lorsqu'on a par exemple besoin de place et qu'on n'a pas envie de chercher quels doublons supprimer, lier les doublons entre eux fait qu'ils prennent moins de place sur le disque dur (n fichiers doublons prennent la place d'un seul fichier) tout en gardant leur présence (supprimer l'un ne supprime pas les autres).
Ce système peut se montrer utile dans d'autres cas de figures, mais ça devient un autre sujet tongue

$ link_doublons.sh
Usage: link_doublons.sh [-v] [--exec | --noexec] [--taille taille] rep [ rep ... ]
  Cherche les doublons dans les répertoires qu'on lui spécifie, et les remplace par des liens durs (hard links).
  [-v]
     Mode verbeux (désactivé par défaut)
  [--exec | --noexec]
      Exécute le script de liaison des doublons sans poser la question
      N'exécute pas le script de liaison des doublons sans poser la question
  [--taille taille]
      Spécifie la taille des doublons à lier
      Par exemple :
        1  : Doublons dont la taille est d'au-moins   1 octet
        2  : Doublons dont la taille est d'au-moins  10 octets
        3  : Doublons dont la taille est d'au-moins 100 octets
        4  : Doublons dont la taille est d'au-moins   1 ko
        7  : Doublons dont la taille est d'au-moins   1 Mo (défaut)
        10 : Doublons dont la taille est d'au-moins   1 Go
  rep
      Répertoire dans lequel chercher les doublons à lier
  [ rep ... ]
      Répertoires supplémentaires dans lesquels chercher les doublons à lier

Ce script commence donc par rechercher les doublons avec fdupes dans les répertoires qu'on lui donne.
Il génère alors, dans le répertoire courant, un fichier yymmjj-HHMM-fdupes.log qui contient le résultat de la commande.

Il se base alors sur ce fichier pour générer un script shell, yymmjj-HHMM-link_doublons.sh, permettant de lier les doublons entre eux.

Une fois le script shell généré, il demande s'il doit être exécuté (à moins que l'une des options exec ou noexec n'ait été activée).

Par défaut, il ne cherche que les doublons dont la taille est supérieure ou égale à 1000000 octets (1Mo), à moins que l'option taille ne soit utilisée.

Enfin, le script est par défaut silencieux. On peut le faire causer davantage en activant le mode verbeux.

En exemple :
Les fichiers abc, abc2, abc3 sont ici identiques. Idem pour les fichiers defghij, defghij2, defghij3, defghij4.

$ find -type f -ls
701933    4 -rw-------   1 borx     borx            8 juin 15 00:18 ./rep2/rep4/defghij4
701931    4 -rw-------   1 borx     borx            8 juin 15 00:18 ./rep2/defghij2
701836    4 -rw-------   1 borx     borx            4 juin 15 00:18 ./rep2/abc2
701912    4 -rw-------   1 borx     borx            8 juin 15 00:18 ./rep1/defghij
701831    4 -rw-------   1 borx     borx            4 juin 15 00:17 ./rep1/abc
701932    4 -rw-------   1 borx     borx            8 juin 15 00:18 ./rep1/rep3/defghij3
701911    4 -rw-------   1 borx     borx            4 juin 15 00:18 ./rep1/rep3/abc3

$ du -sb .
20524	.

Je lance le script avec ses paramètres par défaut sur le répertoire en question.

$ link_doublons.sh .
Aucun doublon à lier trouvé

Bah oui, la taille des doublons recherchés est trop grande pour mes tous petits fichiers d'exemple tongue.

$ link_doublons.sh --taille 1 .
Lancer la liaison des doublons ? (y/Y/o/O/n/N)

Les options exec ou noexec auraient pu répondre elles-mêmes à la question posée.
Mais avant de répondre à la question, voyons les 2 fichiers créés par le script :

$ more 090615-0027-fdupes.log
Résultat de la commande fdupes -rnS .
4 bytes each:
./rep1/abc
./rep2/abc2
./rep1/rep3/abc3

8 bytes each:
./rep1/defghij
./rep2/defghij2
./rep1/rep3/defghij3
./rep2/rep4/defghij4

$ more 090615-0027-link_doublons.sh
#!/bin/bash

ln -fv "./rep1/abc" "./rep2/abc2"
ln -fv "./rep1/abc" "./rep1/rep3/abc3"

ln -fv "./rep1/defghij" "./rep2/defghij2"
ln -fv "./rep1/defghij" "./rep1/rep3/defghij3"
ln -fv "./rep1/defghij" "./rep2/rep4/defghij4"

On répondant oui à la question, le script ci-dessus est lancé, sinon on peut le garder pour plus tard, et dans tous les cas, ça laisse une trace de ce qui a été fait...

Après avoir répondu oui :

$ find -type f -ls
701937    4 -rwx------   1 borx     borx          224 juin 15 00:27 ./090615-0027-link_doublons.sh
701935    4 -rw-------   1 borx     borx          182 juin 15 00:25 ./090615-0027-fdupes.log
701912    4 -rw-------   4 borx     borx            8 juin 15 00:18 ./rep1/defghij
701912    4 -rw-------   4 borx     borx            8 juin 15 00:18 ./rep2/defghij2
701912    4 -rw-------   4 borx     borx            8 juin 15 00:18 ./rep1/rep3/defghij3
701912    4 -rw-------   4 borx     borx            8 juin 15 00:18 ./rep2/rep4/defghij4
701831    4 -rw-------   3 borx     borx            4 juin 15 00:17 ./rep1/abc
701831    4 -rw-------   3 borx     borx            4 juin 15 00:17 ./rep2/abc2
701831    4 -rw-------   3 borx     borx            4 juin 15 00:17 ./rep1/rep3/abc3

$ du -sb .
20898	.
$ rm 090615-0042-*
$ du -sb .
20492	.

Le résultat n'a pratiquement pas changé. Les fichiers sont toujours là, et font toujours la même taille, sauf qu'ils pointent désormais tous vers le même i-noeud que leurs doublons et qu'ils occupent donc désormais moins de place...


Le script :

#!/bin/bash

# Fonctions globales
###############################################################################

# Affiche les paramètres sur la sortie standard si le mode verbeux est activé
displayInfo() {
	$VERBOSE && cat <<EOF
$*
EOF
	return 0
}

# Affiche les paramètres sur la sortie d'erreur
displayError() {
	cat >&2 <<EOF
$*
EOF
	return 0
}

# Arrête l'exécution du script avec un certain code retour et en affichant
# préalablement un message sur la sortie d'erreur
throwError() {
	RETURN_VALUE=$1
	shift
	displayError "$*"
	exit $RETURN_VALUE
}

# Affiche sur la sortie d'erreur le mode d'usage du script
usage() {
	throwError 1 \
"Usage: $0 [-v] [--exec | --noexec] [--taille taille] rep [ rep ... ]
  Cherche les doublons dans les répertoires qu'on lui spécifie, et les remplace par des liens durs (hard links).
  [-v]
     Mode verbeux (désactivé par défaut)
  [--exec | --noexec]
      Exécute le script de liaison des doublons sans poser la question
      N'exécute pas le script de liaison des doublons sans poser la question
  [--taille taille]
      Spécifie la taille des doublons à lier
      Par exemple :
        1  : Doublons dont la taille est d'au-moins   1 octet
        2  : Doublons dont la taille est d'au-moins  10 octets
        3  : Doublons dont la taille est d'au-moins 100 octets
        4  : Doublons dont la taille est d'au-moins   1 ko
        7  : Doublons dont la taille est d'au-moins   1 Mo (défaut)
        10 : Doublons dont la taille est d'au-moins   1 Go
  rep
      Répertoire dans lequel chercher les doublons à lier
  [ rep ... ]
      Répertoires supplémentaires dans lesquels chercher les doublons à lier"
}


# Fonctions spécifiques
###############################################################################

recherche_doublon() {
	# On recherche des doublons dans les répertoires fournis
	displayInfo "Recherche des doublons (Résultats dans $fdupes_log)"
	echo "Résultat de la commande fdupes -rnS $*" > $fdupes_log
	$VERBOSE || quiet='q'
	fdupes -rnS$quiet $* >> $fdupes_log
	return $?
}

construire_script() {
	# On initialise le script shell de sortie
	displayInfo "Création du script $link_doublons_sh"
	echo -e '#!/bin/bash\n' > $link_doublons_sh
	chmod u+x $link_doublons_sh

	ignore=true
	i=0

	# On parcourt chaque ligne du résultat du fdupes
	while read ligne; do
		# Si la ligne commence par un nombre de n chiffres
		if echo $ligne | grep -Eq "^[0-9]{$taille}.* byte.* each:$"; then
			# Alors on n'ignorera pas les lignes qui suivront
			ignore=false
		# Pour chaque ligne à ne pas ignorer
		elif [ "$ignore" == "false" ]; then
			# Si la ligne n'est pas vide
			if [ -n "$ligne" ]; then
				# On garde le nom du fichier dans un tableau
				fic[$i]="$ligne"
				i=$(($i + 1))
			# Dès qu'on rencontre une ligne vide
			else
				# On lie le premier élément du tableau vers le deuxième
				# puis vers le troisième, puis vers le quatrième, ...
				for j in $(seq 1 $(($i - 1))); do
					echo "ln -fv \"${fic[0]}\" \"${fic[$j]}\"" >> $link_doublons_sh
				done
				echo "" >> $link_doublons_sh
				# On remet les compteurs à zéro, et on recommence
				unset fic
				i=0
				ignore=true
			fi
		fi
	done < "$fdupes_log"
}


# Vérification des dépendances
###############################################################################
which fdupes >/dev/null 2>&1 || throwError 4 "Fonctionnement impossible sans fdupes"


# Initialisation des paramètres avec les valeurs par défaut
###############################################################################

# Mode verbeux (désactivé par défaut)
VERBOSE=false

# Taille des doublons à lier
taille=7

# Lancement automatique du script
lancerScriptLiaison=


# Initialisation des paramètres en fonction des saisies utilisateurs
###############################################################################

# Récupération des paramètres
TEMP=$(getopt -o v --long exec,noexec,taille: -n "$0" -- "$@")
[ $? != 0 ] && usage
eval set -- "$TEMP"

# Traitement des paramètres
while true ; do
        case "$1" in
                --exec)   lancerScriptLiaison='y'; shift;;
                --noexec) lancerScriptLiaison='n'; shift;;
                --taille) taille=$2;               shift 2;;
                -v)       VERBOSE=true;            shift;;
                --) shift; break;;
                *) usage;;
        esac
done


# Contrôle des paramètres
###############################################################################

# Si aucun argument fourni alors arrêt du script avec affichage du mode d'usage
[ -z "$1" ] && usage

# Contrôle des paramètres numériques
[ $taille -gt 0 ] 2> /dev/null || throwError 2 "Paramètre 'taille' incorrect"


# Lancement de la procédure
###############################################################################

fdupes_log="$(date +%y%m%d-%H%M)-fdupes.log"
recherche_doublon $*

# Si aucune ligne du résultat du fdupes ne commence par n chiffres
# Alors on arrête tout de suite
grep -Eq "^[0-9]{$taille}.* byte.* each:$" "$fdupes_log" || throwError 3 "Aucun doublon à lier trouvé"

link_doublons_sh="$(date +%y%m%d-%H%M)-link_doublons.sh"
construire_script

[ -z "$lancerScriptLiaison" ] && read -p "Lancer la liaison des doublons ? (y/Y/o/O/n/N) " lancerScriptLiaison
$VERBOSE || exec 1> /dev/null
echo $lancerScriptLiaison | grep -qE "y|Y|o|O" && ./$link_doublons_sh

Dernière modification par BorX (Le 29/06/2009, à 22:56)

Hors ligne

#2 Le 29/06/2009, à 23:03

lamte01

Re : Script Shell qui transforme les fichiers doublons en liens durs

les proseduire d'instalation ubuntu sur une cle USB ou un lien

Hors ligne

#3 Le 01/07/2009, à 10:03

BorX

Re : Script Shell qui transforme les fichiers doublons en liens durs

Excuse-moi, je crains de ne pas comprendre ta suite de mots... hmm

Hors ligne

#4 Le 02/07/2009, à 14:09

BorX

Re : Script Shell qui transforme les fichiers doublons en liens durs

Bon, il semble que l'utilitaire fslint fasse, entre autres, ce genre d'opérations. roll
Je ne l'ai pas encore essayé, j'énumérerai les différences une fois que je l'aurai essayé.

Hors ligne

#5 Le 01/05/2010, à 09:19

nesthib

Re : Script Shell qui transforme les fichiers doublons en liens durs

sympa BorX smile effectivement plus complet que le mien, dans le principe c'est la même chose, c'est vrai que je n'ai pas cherché très longtemps si ça existait déjà… j'ai codé ça rapidos pour répondre à une question d'un membre de mon GUL

juste quelques petites remarques :
- même si cela te permets de le modifier et de le lancer plus tard je ne suis généralement pas très fan de faire un script qui créé un script (du moins pour un script à distribuer à des débutants)
- pourquoi utiliser un tableau pour stocker tes noms de fichiers ?

ps. veux-tu que je déplace ton fil dans "trucs astuces et scripts utiles" ?


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#6 Le 30/07/2013, à 09:36

jibe

Re : Script Shell qui transforme les fichiers doublons en liens durs

Salut,

Désolé de déterrer ce vieux sujet, mais

BorX a écrit :

Bon, il semble que l'utilitaire fslint fasse, entre autres, ce genre d'opérations. roll
Je ne l'ai pas encore essayé, j'énumérerai les différences une fois que je l'aurai essayé.

Le comparatif m'intéresserait. Si l'essai a été fait...

nesthib a écrit :

ps. veux-tu que je déplace ton fil dans "trucs astuces et scripts utiles" ?

fais donc un hardlink tongue
(plus sérieusement, mais complètement hors sujet, c'est une possibilité que je n'ai jamais vue sur les forums, mais qui serait intéressante et utile ! Ce sujet en est un bon exemple, puisqu'il irait aussi bien là-bas qu'ici)


Il y a deux manières de paraitre supérieur : en montrant sa valeur ou en dévalorisant les autres.

Hors ligne

#7 Le 30/07/2013, à 16:38

BorX

Re : Script Shell qui transforme les fichiers doublons en liens durs

Salut,

Houla ! Vieux sujet en effet !
3 ans déjà ! De l'eau a coulé sous les ponts, depuis...

J'ai utilisé FSlint pendant un moment.
C'est un utilitaire assez pratique, qui fait, notamment, la même chose que ce script.
Il permet de repérer les doublons et, dès lors, de faire des opérations dessus : s'en débarrasser, en faire des hardlinks, ...
Il se présente sous la forme d'une GUI, donc plus conviviale, mais qu'on ne peut pas automatiser, contrairement au script.
Il faut l'essayer et s'en servir de temps en temps pour réorganiser ses arborescences, gagner en place, ... bref faire le ménage.
FSlint

Personnellement, je joue toujours du hardlink principalement pour mes sauvegardes sur disques durs externes (gain de place), avec un script maison (à base de rsync) que je ne crois pas avoir posté sur ce forum.

Parallèlement, j'expérimente des sauvegardes avec git qui répond autrement à la problématique.
Il référence chaque fichier, à partir de son empreinte SHA1, dans un fichier à part. Ainsi, 2 fichiers indépendants mais identiques sont référencés par git au sein du même fichier.
Ca évite de chercher les doublons pour en faire des hardlinks (git le fait), et ça permet à l'un des doublons d'être modifié sans forcément modifier l'autre (cerise sur le gâteau : en gardant l'historique).
Bref, de l'eau a coulé sous les ponts... smile

Mais il faut essayer FSlint wink
http://www.pixelbeat.org/fslint/

Quant à l'idée du topic multi-rubriques, l'idée est bonne.
En gros, on remplace le système de rubriques par un système de tags. Un topic ne se retrouve donc plus dans une et une seule rubrique, mais appartient à un ou plusieurs tags...
Par contre, l'administration risque d'être bien plus ardue hmm

Hors ligne

#8 Le 30/07/2013, à 22:13

jibe

Re : Script Shell qui transforme les fichiers doublons en liens durs

Merci pour ces explications. Mais je comprends mal si ton script fait exactement la même chose (ni plus, ni moins), ou s'il apporte quelques avantages. Tu parles d'automatisation, c'est un point qui peut être intéressant ! Y en a-t-il d'autres ?

Un tel outil peut avoir diverses utilités. Si j'ai bien compris, tu t'en servais surtout pour préparer tes sauvegardes. Moi, c'est simplement pour faire du ménage dans mes disques, avec diverses actions selon les doublons : suppression, transformation en hardlink, en softlink... D'autres y trouveront peut-être d'autres utilisations.

Donc, puisque tu avais proposé un comparatif et puique, bien que le temps ait passé et que tu aies trouvé d'autres manières de procéder, comme tu sembles avoir le sujet à peu près en tête, te le demander est plus simple que télécharger puis étudier ton script et comparer moi-même avec FSlint. Mais bon, si tu n'as pas le temps ou pas envie, ce n'est pas grave : je remuerai ma flemme ! Après tout, le logiciel libre, c'est la liberté d'étudier le code, pas celle d'emm... l'auteur en lui demandant quels sont les atouts de son produit !

BorX a écrit :

Quant à l'idée du topic multi-rubriques, l'idée est bonne.
En gros, on remplace le système de rubriques par un système de tags. Un topic ne se retrouve donc plus dans une et une seule rubrique, mais appartient à un ou plusieurs tags...
Par contre, l'administration risque d'être bien plus ardue hmm

Bon, puisque tu as rebondi sur ce hors-sujet, je continue. Pour ma part, quand je parlais de hardlink, ça représentait exactement ce à quoi je pensais. Il pourrait être intéressant qu'un sujet puisse être référencé dans plusieurs rubriques, et donc qu'une fois créé dans l'une d'entre elles, on (l'auteur, les modos...) puisse créer un lien qui pointe dessus dans une autre rubrique. AMHA, ça ne rendrait pas l'administration plus hardue, puisqu'il n'y aurait toujours qu'un seul sujet. Simplement un peu plus de surveillance pour éviter que de tels référencements multiples soient utilisés à bon escient.


Il y a deux manières de paraitre supérieur : en montrant sa valeur ou en dévalorisant les autres.

Hors ligne

#9 Le 30/07/2013, à 23:19

BorX

Re : Script Shell qui transforme les fichiers doublons en liens durs

smile
J'ai fait ce script quand j'ai commencé à mettre à profit certains avantages des hardlinks.
En le présentant dans ce topic, c'est principalement ces avantages que je mettais en avant, tout en proposant aux intéressés d'utiliser le script.
Je ne connaissais pas encore FSlint à l'époque.
Depuis, j'ai joué avec et, (de mémoire,) FSlint propose bien plus de fonctionnalités que ce script, tant au niveau de la recherche des fichiers que des opérations qu'on peut ensuite effectuer.
Donc, utilise-le ! wink

Après, si tu veux faire de l'automatisation, alors fais du scripting !
Pour ce faire, tu peux naturellement t'inspirer du script présenté ici
Cependant,
1) il faut que l'automatisation soit un besoin, et que ce besoin soit défini, sinon c'est pas la peine
2) il faut connaître (ou vouloir apprendre) le scripting

Note : ce script n'est pas vraiment optimisé pour de l'automatisation, puisqu'il génère un autre script qui peut être revu et modifié avant exécution.
C'est utile pour une exécution ponctuelle (et dans ce cas, il vaut mieux utiliser FSlint wink), mais pour de l'automatisation, je rejoins l'avis de nesthib qui n'aime pas les scripts qui génèrent des scripts.

Bref, utilise FSlint wink
Mais fais gaffe à ce que tu fais, aussi...
C'est le genre d'outils avec lesquels une fausse manip' peut faire mal.
Alors fais des essais dans un répertoire de tests dans lequels tu auras balancé en doublons quelques gros fichiers, mp3, divx, quelques fichiers textes, des images, etc...

Hors ligne

#10 Le 31/07/2013, à 08:18

Brunod

Re : Script Shell qui transforme les fichiers doublons en liens durs

Je me permets juste de préciser, au cas où ce ne serait pas clair, que l'on peut faire des scripts appelant fslint qui est utilisable en ligne de commande.


Windows est un système d'exploitation de l'homme par l'ordinateur. Linux, c'est le contraire...
39 pc linux convertis

Hors ligne

#11 Le 31/07/2013, à 09:47

BorX

Re : Script Shell qui transforme les fichiers doublons en liens durs

Et bah tout est dit ! smile
Le script de ce topic n'a donc qu'une utilité pédagogique (et encore roll)

Dernière modification par BorX (Le 31/07/2013, à 09:48)

Hors ligne