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 :

script shell : comparer 2 répertoires entre eux


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 46
    Par défaut script shell : comparer 2 répertoires entre eux
    Bonjour,

    voila j'ai realisé un petit script shell qui permet, en passant 2 repertoire en argument, de les comparer et de renvoyer un code annonçant s'ils sont identique ou non (dans leur contenu aussi).
    Le probleme est que j'ai besoin de me deplacer dans les repertoire dans le script, et que ça me renvoi cette erreur "can't cd to..."

    Voici mon code :
    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
     
    # si le nombre d'arguments n'est pas egal a 2
    if [ $# -ne 2 ]; then
     
        echo "Erreur : Il faut 2 arguments."
     
    # sinon, si le nombre d'arguments est egal a 2
    elif [ $# -eq 2 ]; then
     
    	path=`pwd`
     
        # si les deux arguments sont des repertoires
        if [ -d $1 ] && [ -d $2 ]; then
     
    	# on liste le contenu du repertoire qui contient le plus d'elements
    	if [ `ls -l $1 | wc -l` -gt `ls -l $2 | wc -l` ]; then
    	    rep1=$1
    	    rep2=$2
    	else
    	    rep1=$2
    	    rep2=$1
    	fi	
     
    	# listage du repertoire qui a le plus d'elements
    	contentrep1=`ls $rep1`
     
    	# on les elements de rep1
    	for var in $contentrep1
    	  do
    	  # on se place dans $rep1
    	  cd $rep1
    	  # si $var est un fichier dans $rep1
    	  if [ -f $var ]; then
    	      # on se place dans rep2
    	      cd $rep2
    	      # si $var n'est pas un fichier dans $rep2
    	      if [ ! -f $var ]; then
    		  echo "Code de retour : 1"
    		  exit 1
    	      fi
    	  # sinon, si $var est un repertoire dans $rep1
    	  elif [ -d $var ]; then
    	      # on se place dans $rep2
    	      cd $rep2
    	      # si $var n'est pas un repertoire dans $rep2
    	      if [ ! -d $var ]; then
    		  echo "Code de retour : 1"
    		  exit 1
    	      fi
    	  fi
    	done
    	# si on arrive ici, c'est que les deux repertoires sont identiques
    	echo "Code de retour : 0"
    	exit 0
     
     
        fi
    fi
    Voila, j'ai essayé plein de bidouillages syntaxique mais je n'y arrive pas
    Si quelqu'un connait une solution ou une alternative merci d'avance

    ++

  2. #2
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Citation Envoyé par chicna Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ...
    	  # on se place dans $rep1
    	  cd $rep1
    	  # si $var est un fichier dans $rep1
    	  if [ -f $var ]; then
    	      # on se place dans rep2
    	      cd $rep2
    ...
    Avec le premier cd, tu vas dans $rep1 - cela fonctionne sans problème.
    Tu es maintenant dans $rep1, et tu cherches à faire : cd $rep2
    Ca ne peut pas fonctionner, puisque $rep2 n'est pas forcément inclus dans $rep1

    Pour débugger ton script, je te conseil d'ajouter, en tant que première ligne :Ensuite, mets des 'pwd' un peu partout, ça te montrera que tu as des soucis de répertoire.

    Par la suite, tu déplaceras le set -x plus bas dans ton script, là où tu as un soucis.

    Ah oui, un dernier point : un script commence par le shell qu'il utilise, avec par exemple la syntaxe suivante, en supposant que tu utilises bash :
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  3. #3
    Membre émérite
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #!/bin/bash                                                                                             
     
    file1="/tmp/file1.$$"
    for i in `find ${1} | sed 1d` ; do echo "${i##${1}}" >> ${file1}  ; done
     
    file2="/tmp/file2.$$"
    for i in `find ${2} | sed 1d` ; do echo "${i##${2}}" >> ${file2}  ; done                                
     
    diff ${file1} ${file2} > /dev/null
    Dans l'état, il n'y a pas de contrôle de paramètres.
    Ca crée deux fichiers temporaires dans /tmp (donc suppose un droit en écriture), récupère dans chacun de ces fichiers le contenu de chaque répertoire (excepté le nom du répertoire lui même, qui peut être différent, d'où le sed 1d). Dans chaque fichier, on récupère le chemin complet de chaque sous répertoire et fichier

    Si par exemple j'ai
    a
    a/b
    a/b/c
    a/b/c/d
    Alors, j'aurai dans mon fichier
    /b
    /b/c
    /b/c/d
    Puis enfin diff pour comparer (en jetant la sortie, seul le code de retour intéresse).

    Tel quel, le script retourne directement la valeur de diff, donc 0 si OK, 1 sinon.

    Il faudrait rajouter des contrôles sur les paramètres, éventuellement supprimer les fichiers temporaires, etc. Et modifier find si tu veux chercher de façon plus fine, bien sûr.
    Je me contente de te montrer une base potentielle

    Pose des questions si tu ne comprends pas.

    <edit>
    Petit conseil supplémentaire : plutôt que d'utiliser cd dans les scripts, je te conseille fortement le couple pushd/popd plus facile à gérer
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 46
    Par défaut
    ok, c'etait donc une simple erreur de logique. Merci ^^

    Ma solution :
    path=`pwd` au debut du script ;
    cd $path avant chaque cd ;
    ça marche .

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    627
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 627
    Par défaut
    Citation Envoyé par Pouic Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in `find ${2} | sed 1d` ; do echo "${i##${2}}" >> ${file2}  ;
    désolé de remonter ce topic mais je ne comprends pas trop ce code mais c'est quoi ${2}.a quoi ce là correspond car je ne vois pas qu'il est défini nulle part.merci

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par bigs3232 Voir le message
    désolé de remonter ce topic mais je ne comprends pas trop ce code mais c'est quoi ${2}.a quoi ce là correspond car je ne vois pas qu'il est défini nulle part.merci
    Salut

    Les $1 $2 $3 $4 ... (jusqu'à $9) correspondent aux arguments du script.
    Si tu lances le script de cette manière: script toto titi tata<return> alors $1 contiendra toto, $2 contiendra titi et $3 contiendra tata. Cette affectation est faite automatiquement par le shell donc tu n'as pas besoin de les définir, mais seulement de les utiliser si tu en as envie/besoin. On les nomme les "paramètres positionnels".

    Les accolades servent à isoler le nom de la variable en cas d'ambigüité possible.
    Exemple
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    prix=10
    echo "Mon carambar coûte $prixcts"
    Ici, le shell essaiera d'afficher la variable "prixcts" (qui n'existe pas) et ne comprendra pas que tu veux afficher $prix suivi des lettres "cts"

    Pour éviter ce pb, on encapsule le nom de la variable avec des accolades
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    prix=10
    echo "Mon carambar coûte ${prix}cts"
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Citation Envoyé par Sve@r Voir le message
    Les $1 $2 $3 $4 ... (jusqu'à $9) correspondent aux arguments du script.
    Et au-delà si tu les entoures avec des accolades ${10}, ${25}, ${101}, etc.


Discussions similaires

  1. Comment comparer plusieurs tableaux entre eux ?
    Par djibril dans le forum Téléchargez
    Réponses: 2
    Dernier message: 21/08/2012, 13h14
  2. script shell et arguments en entrée
    Par Lolitaaa dans le forum Linux
    Réponses: 7
    Dernier message: 03/07/2010, 11h17
  3. Script shell - gestion user, touche entrée
    Par monsieur75 dans le forum Linux
    Réponses: 23
    Dernier message: 31/03/2009, 17h24
  4. Comparer 2 picturebox entre eux
    Par offspring dans le forum C#
    Réponses: 4
    Dernier message: 18/04/2008, 19h13
  5. Filtrer une table en comparant deux champs entre eux
    Par damene dans le forum Débuter
    Réponses: 13
    Dernier message: 12/04/2008, 19h10

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