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 :

[SH] Script qui dysfonctionne sur Mint mais pas sur Mageia ?


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Femme Profil pro
    Chargé de référencement
    Inscrit en
    Septembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Chargé de référencement

    Informations forums :
    Inscription : Septembre 2019
    Messages : 4
    Par défaut [SH] Script qui dysfonctionne sur Mint mais pas sur Mageia ?
    Bonsoir tout le monde,

    Je fais appel à vous en désespoir de cause :
    Ne trouvant un logiciel qui me convienne exactement, je me suis bricolé (ou plus exactement adapté) un script pour nettoyer les répertoires en cas de copie de sauvegarde
    MAIS
    je me suis rendu compte que mon script ne fonctionne pas sur Mint 18 32 bits (alors qu'il fonctionne sur Mageia 5 et 6).

    Voici le script qui pose problème :
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    #!/bin/sh
     
    # Adapte de : nicofo - http://nicofo.tuxfamily.org
    # 24/06/07 -  24/04/2012
     
    #compare 2 dossiers et supprimme les fichiers identiques au niveau nom et taille
     
    read -p "Dossier 1 (Ne sera pas modifié) : " DIR1 || DIR1="$1"
    [ ! -d "$DIR1" ] && echo "'$DIR1' n'est pas un dossier !" && exit 1
    read -p "Dossier 2 (Les fichiers en double seront supprimmés): " DIR2 || DIR2="$2"
    [ ! -d "$DIR2" ] && echo "'$DIR2' n'est pas un dossier !" && exit 1
     
    #remplacer "/" par "\/" (pour le sed)
    DIR1m=$(echo "$DIR1"|sed "s#/#\\\/#g")
    DIR2m=$(echo "$DIR2"|sed "s#/#\\\/#g")
     
    [ "$DIR1" == "$DIR2" ] && echo "Dossier 1 et Dossier 2 sont identiques" && exit 1
     
    HEUREDEBUT=$(date +'%s')
     
    file2="/tmp/compDossier2"
     
    #ajouter le cas échéant un "/" final aux noms de dossier
    [ -z "$(echo "$DIR1"|grep "/$")" ] && DIR1="$DIR1/"
    [ -z "$(echo "$DIR2"|grep "/$")" ] && DIR2="$DIR2/"
     
    #lister le dossier 2 (celui dont les fichiers vont être supprimmés)
    echo -en "\r\033[K\033[1;34mPréparation : listage de \"$DIR2\" ...\033[0m"
    find "$DIR2" | sed "s/^$DIR2m//" >$file2
     
    echo -e "\r\033[K\033[1;34mSuppression des fichiers identiques par leur nom et leur taille:\033[0m"
    echo "(espace) = Répertoire. Ne rien faire."
    echo " . = Différence entre les 2 fichiers comparés. Ne rien faire."
    echo " : = Les 2 fichiers comparés sont identiques. Effacer le fichier de l'ancien répertoire de sauvegarde."
    echo ""
     
    NbLignes=`more $file2 | wc -l`
    echo "Nombre de fichiers et répertoires a vérifier : " $NbLignes
    Pas=$(expr $NbLignes / 100)
    echo "Taille du répertoire 2 AVANT traitement  : " 
    TailleAvant=`du -s "$DIR2"| awk -F" " '{ print $1 }'`
    echo $TailleAvant  " Octets"
     
    # Si le fichier est présent dans le DIR2 et qu'il a la même taille que sur DIR1 -> Effacer. Si non, ne rien faire
    echo ""
    echo "Début du Traitement ..."
    old_IFS=$IFS     # sauvegarde du séparateur de champ  
    IFS=\$'\r\n'     # nouveau séparateur de champ, le caractère fin de ligne  
    i=-1
    j=0
    k=0
    for ligne in $(cat $file2)
    do
      i=$((++i)) 
        #echo $i " / " $j
      if [ $i -ge $j ]; then 
        j=$((j+Pas))
        k=$((++k)) 
        echo -n " $k% " # indiquer le pourcentage pour avoir une idée de l'avancement
      fi
      #echo $DIR1$ligne " / " $TAILLE1 " // " $TAILLE2 " / " $DIR2$ligne " | " $ligne
     # Si la ligne a tester contient un nom de fichier suivre le traitement normal, si nom de repertoire, passer a la ligne suivante
     if [ `stat -c %F $DIR2$ligne` 2>/dev/null = 'fichier' ]; then
        if [ `stat -c %s $DIR1$ligne 2>/dev/null` = `stat -c %s $DIR2$ligne` 2>/dev/null ]; then
          rm  -f "$DIR2$ligne"
          echo -n ":" # Si identique = Supp
          #echo $DIR2$ligne
        else
          echo -n "." # Si différents = Suivant
          #echo $ligne
        fi
       else
        echo -n " " # Si répertoire = Suivant
        #echo $ligne
      fi 
    done
    IFS=$old_IFS     # rétablissement du séparateur de champ par défaut
     
    TailleApres=`du -s "$DIR2"| awk -F" " '{ print $1 }'`
    echo ""
    echo " Taille du répertoire 2 APRES traitement  : " $TailleApres  " Octets"
     
    GainTaille=$(expr $TailleApres - $TailleAvant)
    GainTailleKo=$(expr $GainTaille / 1024)
    echo "Gain de place : " $GainTaille " Octets (" $GainTailleKo " KiloOctets)"
     
    rm $file2 
     
    HEUREFIN=$(date +'%s')
    DureeExecution=$(($HEUREFIN - $HEUREDEBUT))
    DureeExecutionM=$(expr $DureeExecution / 60)
    echo "Durée du traitement : " $DureeExecution " Secondes (" $DureeExecutionM " Minutes)"
    Après recherche, le problème semble se situer au niveau de la manipulation du séparateur de champ ($IFS).
    SI je passe un répertoire ou un fichier contenant 'r' ou 'n', le répertoire se scinde en 2 lignes, ce qui engendre une erreur.
    (exemple : /home/toto/martie/Documents se traduit au niveau du script par 2 lignes : /home/toto/ma et tie/Documents)
    J'ai tout essayé : En elevant ce changement de caractère, en le modifiant vers \r seul ou \n seul, en bash, en ksh, ....

    Quelqu'un peut-il me dire comment faire pour que ce script fonctionne sur les 2 plateformes SVP ?

    Cela me ferais très plaisir car je commence à ne plus avoir beaucoup de cheveux .......

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 636
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 636
    Par défaut
    Bonjour,

    ce script est truffé d'erreur. -> poubelle.

    rien que le première ligne de code est une erreur : on teste si le script a un argument, autrement on demande à l'utilisateur d'entrée une donnée
    et la deuxième aussi : test -d "$rep" || { >&2 echo "Err: exit"; exit 1;}.
    la suite est du même tonneau.
    -> poubelle

    il est excessivement compliqué, manque de cohérence, et il est long...
    -> poubelle.

    et ce n'est pas comme ça qu'on lit un fichier en shell : lire un fichier en shell

    ça veut dire quoi "nettoyer les répertoires en cas de copie de sauvegarde" ?
    tu peux décrire les étapes nécessaires à la réalisation de ce nettoyage ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Chargé de référencement
    Inscrit en
    Septembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Chargé de référencement

    Informations forums :
    Inscription : Septembre 2019
    Messages : 4
    Par défaut
    Bonjour,

    Tout d'abord, merci pour la réponse.

    Je dois avouer que je ne suis pas un pro en shell. Je me suis contenté de prendre un script existant et de le modifier jusqu'à ce qu'il me convienne. Je n'ai pas cherché à approfondir.

    Je vais regarder ces histoires d'erreurs de code, si je peux le simplifier (en regardant le lien vers la lecture de shell)

    "nettoyer les répertoires en cas de copie de sauvegarde" = Si je fais une copie de sauvegarde d'un répertoire par exemple (copier/coller), ce script permet de supprimer les fichiers identiques entre la sauvegarde et le répertoire source.

    Etapes du script :
    - Donner le répertoire qui ne sera pas modifié (source)
    - Donner l'ancien répertoire (dans lequel les doubles seront retirés)
    - calcul du nombre de fichiers à vérifier et de la taille totale (pour évaluer le gain de place)
    - pour chaque fichier dans l'ancien répertoire, vérifier s'il est identique à celui du nouveau répertoire,si oui, le supprimer.
    Enfin, indiquer le temps de traitement et le gain de place

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 636
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 636
    Par défaut
    si /bin/sh est une contrainte (/bin/sh n'est pas toujours un lien vers /bin/bash), alors == ne fonctionnera pas, c'est un "bashisme").

    il faut aussi être précis dans l'énoncé de l'algorithme, et rédiger cet algorithme avant de coder.
    cela permet de prévoir ce qu'il faut mettre en œuvre, les notions à acquérir, et trouver la manière optimale de faire.
    et tu n'aurais donc pas à modifier l'IFS, parce que quand on code en respectant les règles de bonnes pratiques, c'est inutile.

    le problème de récupérer un script, c'est de ne pas acquérir les prérequis du langage pour faire quelque chose qui ne ressemble pas à une usine à gaz.
    c'est très différent de récupérer un bout de code de quelques lignes pour faire une chose simple et de récupérer un script pour lui faire faire quelque chose de similaire mais pas identique !

    pour ton problème d'IFS, que se passe-t-il sur la ligne de commande quand tu fais précéder un développement de paramètre par un slash ?

    MAIS, si tu lis le fichier en suivant la méthode indiquée, il n'y aura plus de raison de modifier l'IFS !

    ET si tu suivais les bonnes pratiques d'écriture de script, tu n'aurais pas besoin de fichier temporaire.

    ET PUIS, si tu apprenais le B-A-BA de l'écriture de script tu t'éviterais bien des complications :
    - expr est un programme externe inutile, le shell sait faire des calculs sur des entiers
    - wc -l <fichier indique uniquement le nombre de retour à la ligne du fichier
    - find ... -print0 permet de se prémunir des espaces et des retours à la lignes éventuellement contenus dans les noms de fichiers
    ...

    et plein d'autres petites choses qui simplifieraient le script

    je résume :
    définir le langage à utiliser
    décrire un cheminement fluide des opérations à effectuer (synopsis + algorithme détaillé)
    apprendre et mettre en œuvre les bonnes pratiques du langage pour réaliser chaque opération (recherche dans les tutos, les exemples de scripts, les forums; demander de l'aide)
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 283
    Par défaut
    Bonjour

    [Grain de sel] L'algorithme AVANT la définition du langage à utiliser.[/Grain de sel]

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 636
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 636
    Par défaut
    c'est ce qui est préconisé, en effet.

    pourtant, suivant qu'on écrira le code en shell ou en python (ou autres), les opérations ne se déroulent pas de la même manière, et l'algo ne peut donc pas être identique.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Script qui fonctionne sous FireFox mais pas sous IE
    Par Sebastien14 dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 27/01/2009, 10h32
  2. script qui marche en locale mais pas sur le web
    Par koKoTis dans le forum Langage
    Réponses: 7
    Dernier message: 08/09/2008, 16h07
  3. Script qui marche sous Firefox mais pas sous IE
    Par GreatDeveloperOnizuka dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 25/01/2008, 12h04
  4. script qui marche sous ie mais pas sous firefox
    Par sebicool dans le forum Général JavaScript
    Réponses: 18
    Dernier message: 24/05/2007, 00h07
  5. Script qui marche sous FF mais pas sous IE
    Par xclam dans le forum Général JavaScript
    Réponses: 27
    Dernier message: 11/05/2007, 12h26

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