#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
$ 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 .
$ 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...
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.
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 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 : Giroll – Services libres : TdCT.org
Hide in your shell, scripts & astuces : applications dans un tunnel – smart wget – trouver des pdf – install. auto de paquets – sauvegarde 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
Bon, il semble que l'utilitaire fslint fasse, entre autres, ce genre d'opérations.
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...
ps. veux-tu que je déplace ton fil dans "trucs astuces et scripts utiles" ?
fais donc un hardlink
(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.
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...
Mais il faut essayer FSlint
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
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 !
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
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
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 !
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 ), 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
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 !
Le script de ce topic n'a donc qu'une utilité pédagogique (et encore )
Dernière modification par BorX (Le 31/07/2013, à 09:48)
Hors ligne