IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

archiver en gardant des traces


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut archiver en gardant des traces
    Bonjour,

    Je cherche à faire un script pour créer automatiquement des archives de fichiers non utilisés : par exemple, si je n'ai pas accédé à un fichier depuis 1 an, il est automatiquement ajouté à une archive, et transféré ailleurs, le principe étant de libérer de l'espace disque.

    Comme c'est automatique, j'aimerai trouver un moyen de laisser une trace du fichier : par exemple, un fichier texte qui comporte le nom de l'archive créée à la place du fichier que j'aurai archivé.

    Je sais récupérer les noms des fichiers avec find pour l'archivage, mais je ne vois pas comment créer les fichiers 1 par 1 à l'emplacement des fichiers que j'aurai archivé.

    Merci d'avance

  2. #2
    Membre chevronné Avatar de Leeloo_Multiboot
    Profil pro
    Administrateur Unix/Linux
    Inscrit en
    Avril 2008
    Messages
    417
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur Unix/Linux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2008
    Messages : 417
    Par défaut
    Bonjour,

    As-tu un bout de script à nous montrer?

    Dans ton cas, l'utilisation de commandes de base avec une boucle devrait faire l'affaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    find /ton_repertoire -type f -atime=+365 | while read line
    do
    ext=".tar"
    tar -cjf $line$ext $line && echo "Nom du fichier archivé: "$line >> /ton_repertoire/fichier_trace && mv $line$ext /ton/repertoire/darchivage/
    rm -rf $line
    done

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    Après pas mal de tests (je découvre :p) j'en étais arrivé là pour la partie "trace" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/bin/bash
     
    TESTOK=5
    TODAY=`date +%Y%m%d`
    NLINE=0
     
    find /home/test/ -type f -ctime -$TESTOK \> /home/archivage/$TODAY.txt
     
    cat /home/archivage/$TODAY.txt | while read LINE
    do
    	((NLINE++))
    	currentArchive=`sed -n "$NLINE p"  /home/archivage/$TODAY.txt`
    	echo "$TODAY" > $currentArchive.arch
     
    done
    Je suis en train de chercher comment exclure les fichiers créés en trace de l'archivage suivant , mais pour le moment j'ai un message d'erreur avec la condition qu'il m'avais semblé falloir utiliser, à savoir : -wholename pattern - prune

    Merci pour cette aide je vais décortiquer le code pour mieux comprendre les commandes à utiliser

    Edit : à première vue il semble que j'ai loupé pas mal de raccourcis possible :/

  4. #4
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    La réponse de Leeloo_Multiboot est pas mal, mais quelles remarques:
    - autant mettre ext en dehors de la boucle (plus clair, mais je pense que tu l'a écrit à la volée)
    - perso je mettrai le rm -rf sur la même ligne que le tar avec && parce que si jamais le tar foire (par exemple disque non monté, plus de place sur cette partition... etc...), tu n'as rien archivé et en même temps détruit des originaux
    - si tu cherche que des fichiers (-type f) le -r (récursif) du rm ne sert à rien !
    - s'il y a différents fichiers qui ont le même nom, tu vas juste garder le dernier (le code si dessous ne fait rien, c'est moins pire )

    Sinon, Shimegi je n'ai pas tout pigé à ton dernier post

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/bash
    ext=".tgz"
    find "/ton/repertoire" -type f -atime=+365 | while read line
    do
            backup=`basename $line`
            backup="/ton/backup/$backup$ext"
            [ ! -e "$backup" ] && tar cjzf "$backup" "$line" && echo "$line > $backup" >> "/ton/repertoiredetrace/fichier_trace" && rm -f "$line"
    done

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    Ben je cherche comment faire pour éviter que les fichiers créés comme trace lors de l'archivage puissent être eux aussi archivés, donc à les exclure du "find"

    Le man me retourne différentes options de tri par nom (je leur mets une extension .arch pour les identifier), qui serait si j'ai bien tout compris -wholename forme-du-nom-a-exclure -prune

    Mais j'ai visiblement pas pigé un truc comme il faudrait puisque ça ne fonctionne pas

    Je sais pas si j'aurai le temps aujourd'hui d'appliquer la solution, mais je vous tiens au courant

    Encore merci

  6. #6
    Membre chevronné Avatar de Leeloo_Multiboot
    Profil pro
    Administrateur Unix/Linux
    Inscrit en
    Avril 2008
    Messages
    417
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur Unix/Linux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2008
    Messages : 417
    Par défaut
    Ben je cherche comment faire pour éviter que les fichiers créés comme trace lors de l'archivage puissent être eux aussi archivés, donc à les exclure du "find
    Tu n'as pas besoin de créer un fichier de trace par fichier archivé, tu ajoutes au fichier de trace global comme dans les scripts précédents.
    Tu n'as pas besoin d'exclure le fichier de trace, l'option -atime=+365 de find le fait pour toi

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    Citation Envoyé par Shimegi Voir le message
    En fait si : la trace pour chaque fichier permet de savoir à quelle date a été archivé le fichier qu'on cherche, et de récupérer rapidement l'archive sans perdre trop de temps à rechercher dans un fichier log. Le nombre de fichier à traiter est assez important, et je ne suis pas le seul à les utiliser

    L'exclusion est importante aussi, parce que le script final prendra en compte une durée d'inactivité différente en fonction du type de fichier et de sa localisation dans l'arborescence, ça devrais aller de 1 an à 2 semaines. On va donc vite retomber sur un fichier d'archive inactif depuis deux semaines je pense

    J'ai testé la solution de récupérer directement la variable $line pour le traitement sous la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    find [toutes les options] | while reading line
    do
    bzip2 $line
    done
    mais j'ai des erreurs lorsqu'il y a un espace dans le nom du fichier ou dans le nom du dossier qui le contient ; il y a un moyen de passer outre ?

  8. #8
    Membre chevronné Avatar de Leeloo_Multiboot
    Profil pro
    Administrateur Unix/Linux
    Inscrit en
    Avril 2008
    Messages
    417
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur Unix/Linux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2008
    Messages : 417
    Par défaut
    En fait si : la trace pour chaque fichier permet de savoir à quelle date a été archivé le fichier qu'on cherche, et de récupérer rapidement l'archive sans perdre trop de temps à rechercher dans un fichier log. Le nombre de fichier à traiter est assez important, et je ne suis pas le seul à les utiliser
    Rien ne t'empêches de concaténer le nom de ton fichier avec la date d'archivage dans le fichier trace.

    mais j'ai des erreurs lorsqu'il y a un espace dans le nom du fichier ou dans le nom du dossier qui le contient ; il y a un moyen de passer outre ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    find [toutes les options] | while reading line
    do
    bzip2 "$line"
    done
    PS: Il est préférable et recommandé de ne pas utiliser d'espace dans un nom de fichier ou de répertoire pour éviter ce genre de problème

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    yep, perso j'en met jamais, mais on est 5 à utiliser le système de fichiers. Je suis en train de regarder poru faire un script qui va virer tout les espaces et les remplacer par des underscore mais pour le moment il n'est pas récursif :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in /home/*; do mv "$i" `echo $i | tr " " "_"`; done
    je pense qu'il faut que je l'intègre dans une commande find pour le rendre récursif mais je sais pas encore comment, j'essaie de trouver ça

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    j'ai trouvé ça sur internet, je suis preneur de qq explication : ça marche mais je ne comprend pas tout le code pour le moment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #!/bin/bash
     
    #########
    # remplace tout les espaces par des underscores dans la totalite de l'arborescence, en commancant par le haut
    #########
     
    #Remplace les espaces dans les noms de repertoire
     
    SpaceInDirectory() {
    	find . -type d -name "*" -exec bash -c 'name=${1};final=${1// /_}; mv "${name}" "${final}"' - {} \; 2>/dev/null
    }
     
     
    #Remplace les espaces dans les noms de fichiers
     
    SpaceInFile(){
    	find . -type f -exec bash -c 'name=$(basename "$1"); rep=$(dirname "$1"); final=${name// /_}; mv "${1}" 
    "${rep}/${final}"' - {} \; 2>/dev/null
    }
     
     
    remplaceSpaceInDirectory() {
    	SpaceInDirectory
    	for z in $(ls)
    	do
    		if test -d $z
    		then
    			cd $z; remplaceSpaceInDirectory; cd ..
    		fi
    	done
    }
     
     
    remplaceSpaceInFile() {
    	SpaceInFile
    	for z in $(ls)
    	do
    		if test -d $z
    		then
    			cd $z; remplaceSpaceInFile; cd ..
    		fi
    	done
    }
     
     
    remplaceSpaceInDirectory
    remplaceSpaceInFile

  11. #11
    Membre chevronné Avatar de Leeloo_Multiboot
    Profil pro
    Administrateur Unix/Linux
    Inscrit en
    Avril 2008
    Messages
    417
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur Unix/Linux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2008
    Messages : 417
    Par défaut
    Quelle est la partie que tu ne comprends pas?

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    dans l'ordre :

    la variable ${1} je ne comprend pas d'où elle vient ;
    je ne vois pas comment est géré le remplacement des caractères, même si je vois bien quelle partie s'en charge;

    basename et dirname : ce doit être des variable pré établies j'imagine, mais j'en suis pas certain :p

    et l'expression "for z" : ca semble vérifier la "profondeur" de l'arborescence mais pareil, je ne vois pas comment, à moins que le "z" soit reservé pour ça.

  13. #13
    Membre chevronné Avatar de Leeloo_Multiboot
    Profil pro
    Administrateur Unix/Linux
    Inscrit en
    Avril 2008
    Messages
    417
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur Unix/Linux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2008
    Messages : 417
    Par défaut
    la variable ${1} je ne comprend pas d'où elle vient ;
    je ne vois pas comment est géré le remplacement des caractères, même si je vois bien quelle partie s'en charge;
    Je ne connais pas trop toutes les subtilités de bash avec l'option -c, mais en gros, l'option -c permet de spécifier des commandes dans une chaîne (entre simple quote). Si un paramètre est spécifié après la chaîne -, en l'occurrence ici {} (qui est le résultat du find), alors on peut le récupérer dans la chaîne à l'aide de ${1}.

    Signifie qu'on remplace un ou plusieurs espaces (grâce au //) par un underscore.

    basename et dirname : ce doit être des variable pré établies j'imagine, mais j'en suis pas certain :p
    Ce sont des commandes qui permettent de récupérer respectivement le nom d'un fichier ou d'un répertoire avec ou sans extension. Dans ce dernier cas il faut préciser:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    basename ton_fichier ".extension"
    et l'expression "for z" : ca semble vérifier la "profondeur" de l'arborescence mais pareil, je ne vois pas comment, à moins que le "z" soit reservé pour ça.
    C'est une boucle, c'est comme avec l'habituel:

    Pour tout élément que te retournes la commande ls, alors tu as le traitement qui suit.

    cd $z; remplaceSpaceInDirectory; cd ..
    La "récurrence" de la fonction se fait ici, elle se rappelle tant qu'elle trouve des répertoires ou des fichiers (selon la fonction). Une fois au bout, on revient avec le cd ..


    J'ai essayé d'être clair, après j'ai peut être aussi dit quelques bêtises donc n'hésitez pas à me corriger

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    Merci pour ces éclaircissements

    Reste que je pige toujours pas comment la boucle gère la profondeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for z in $(ls) //si je fais "ls" je n'ai que le niveaux courant qui est listé
    	do
    		if test -d $z //si $z est un dossier alors 
    		then
    			cd $z; remplaceSpaceInFile; cd .. //je vais dans le dossier, je fais mon affaire, je remonte au répertoire racine
    		fi
    	done
    donc pour moi la boucle devrait gérer uniquement le répertoire courant et ses sous repertoires directs, non ?

    C'est énervant quand quelque chose marche mais qu'on sait pas pourquoi :p

  15. #15
    Membre chevronné Avatar de Leeloo_Multiboot
    Profil pro
    Administrateur Unix/Linux
    Inscrit en
    Avril 2008
    Messages
    417
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur Unix/Linux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2008
    Messages : 417
    Par défaut
    donc pour moi la boucle devrait gérer uniquement le répertoire courant et ses sous repertoires directs, non ?
    Non

    Dans la fonction remplaceSpaceInDirectory(), on effectue en premier les modifications sur les noms des répertoires, puis pour chaque occurrence contenue dans un "ls", si cette occurrence est un répertoire alors on va dans ce répertoire et on ré-exécute la fonction et on remonte et ainsi de suite.

    $(ls) est interprétée par le Shell à chaque fois qu'il passe dessus, donc à chaque fois que la fonction remplaceSpaceInDirectory() se rappelle.
    La récurrence se fait ici. Par exemple:

    Tu liste ton répertoire courant, tu as 1 élément dedans (qui est un répertoire), donc tu vas dedans et tu ré-appelles la fonction remplaceSpaceInDirectory(). Donc tu vas lister le sous-répertoire de ton répertoire courant, et si dans ce sous répertoire il y a d'autres répertoires, alors rebelotte, nouveau listage, etc...

    Je sais pas si c'est compréhensible...

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 17
    Par défaut
    Ha oué en fait c'est moi qui suis un peu bête -_-' C'est évident si on oublie pas que la fonction fait une boucle sur elle même :p

    Merci pour ta patience

Discussions similaires

  1. afficher des traces pour debug
    Par el3gans dans le forum MFC
    Réponses: 6
    Dernier message: 03/02/2006, 22h32
  2. [Servlet] Effectuer des traces avec log4j
    Par Shiryu44 dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 04/04/2005, 16h43
  3. [JAR] créer une archive .jar contenant des images.
    Par keny dans le forum Général Java
    Réponses: 2
    Dernier message: 14/03/2005, 13h17
  4. [Applet] afficher des traces
    Par greg_one dans le forum Applets
    Réponses: 3
    Dernier message: 05/07/2004, 17h02
  5. Trouver les redirections dans des traces
    Par severine dans le forum Développement
    Réponses: 3
    Dernier message: 21/04/2004, 18h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo