Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/12/2007, 07h40   #1
Invité régulier
 
Homme
Inscription : février 2007
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2007
Messages : 44
Points : 7
Points : 7
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 :
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

++
Chicna est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 04/12/2007, 10h18   #2
Modérateur
 
Avatar de gangsoleil
 
R&D en systemes informatiques bas niveau Unix/Linux
Inscription : mai 2004
Messages : 5 499
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Isère (Rhône Alpes)

Informations professionnelles :
Activité : R&D en systemes informatiques bas niveau Unix/Linux

Informations forums :
Inscription : mai 2004
Messages : 5 499
Points : 9 679
Points : 9 679
Bonjour,

Citation:
Envoyé par chicna Voir le message
Code :
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 :
__________________
Modérateur "C", "Informatique Générale & Hardware" et "Unix"
Les règles du forum
gangsoleil est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 04/12/2007, 10h54   #3
Membre émérite
 
Avatar de Pouic
 
Inscription : octobre 2004
Messages : 668
Détails du profil
Informations personnelles :
Âge : 28
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2004
Messages : 668
Points : 904
Points : 904
Code :
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
Citation:
a
a/b
a/b/c
a/b/c/d
Alors, j'aurai dans mon fichier
Citation:
/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

http://xrenault.developpez.com
API C standard (C ANSI )
Pouic est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 04/12/2007, 19h05   #4
Invité régulier
 
Homme
Inscription : février 2007
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2007
Messages : 44
Points : 7
Points : 7
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 .
Chicna est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/09/2011, 07h39   #5
Nouveau Membre du Club
 
Inscription : janvier 2010
Messages : 291
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 291
Points : 28
Points : 28
Citation:
Envoyé par Pouic Voir le message
Code :
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
bigs3232 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/09/2011, 09h26   #6
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 057
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
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 : 3 057
Points : 4 936
Points : 4 936
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 :
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 :
1
2
prix=10
echo "Mon carambar coûte ${prix}cts"
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 18/09/2011, 09h51   #7
Expert Confirmé
 
Inscription : janvier 2011
Messages : 971
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 971
Points : 2 872
Points : 2 872
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.

__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/09/2011, 12h08   #8
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 076
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 076
Points : 4 177
Points : 4 177
il ne faut pas utiliser ce code (for elem in `commande`; do), c'est générateur d'erreur.

Si ce que retourne la commande contient un espace, la boucle for itérera sur chaque élément retourné.

find peut se suffire à lui-même, en utilisant l'option -exec, ou en pipant sa sortie vers xargs
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 18/09/2011, 14h06   #9
Membre actif
 
Homme
Inscription : août 2011
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : août 2011
Messages : 44
Points : 153
Points : 153
Bonjour,

Pourquoi ne pas utiliser tout simplement diff ?
chardclo est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 19/09/2011, 07h56   #10
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 057
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
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 : 3 057
Points : 4 936
Points : 4 936
Citation:
Envoyé par zipe31 Voir le message
Salut,



Et au-delà si tu les entoures avec des accolades ${10}, ${25}, ${101}, etc.

Yep, mais uniquement dans certains shells (bash oui, ash ou zsh ou ksh je sais pas, sh non)

Citation:
Envoyé par chardclo Voir le message
Bonjour,

Pourquoi ne pas utiliser tout simplement diff ?
Oui, diff ou dircmp. Mais bon, le topic date de 2007 et l'auteur (qui voulait peut-être juste s'exercer) a dû l'oublier depuis donc je ne pense pas que tu auras de réponse à ce sujet. Et là on répondait juste à bigs3232 sur une question de syntaxe...
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 19/09/2011, 09h43   #11
Membre actif
 
Homme
Inscription : août 2011
Messages : 44
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : août 2011
Messages : 44
Points : 153
Points : 153
Citation:
Envoyé par Sve@r Voir le message
Oui, diff ou dircmp. Mais bon, le topic date de 2007 et l'auteur (qui voulait peut-être juste s'exercer) a dû l'oublier depuis donc je ne pense pas que tu auras de réponse à ce sujet. Et là on répondait juste à bigs3232 sur une question de syntaxe...
arg oui, j'ai pô fait gaffe aux dates
chardclo est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 19/09/2011, 14h24   #12
Expert Confirmé
 
Inscription : janvier 2011
Messages : 971
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 971
Points : 2 872
Points : 2 872
Citation:
Envoyé par Sve@r Voir le message
Yep, mais uniquement dans certains shells (bash oui, ash ou zsh ou ksh je sais pas, sh non)
Pour les récalcitrants il ne reste plus qu'à prendre un bon petit shift
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2011, 18h42   #13
Expert Confirmé Sénior
 
Avatar de Sve@r
 
Homme Frédéric
Ingénieur développement logiciels
Inscription : février 2006
Messages : 3 057
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 44
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 : 3 057
Points : 4 936
Points : 4 936
Citation:
Envoyé par zipe31 Voir le message
Pour les récalcitrants il ne reste plus qu'à prendre un bon petit shift
Ben oui, parfois certaines personnes travaillent dans des environnements plus restrictifs/anciens et tous n'ont pas forcément la chance d'avoir du bash

Citation:
Envoyé par zipe31 Voir le message
Et au-delà si tu les entoures avec des accolades ${10}, ${25}, ${101}, etc.
D'un autre coté je ne me souviens pas avoir dû gérer un jour plus de 9 arguments différents (j'en gère parfois des dizaines mais comme ils sont de même nature je fais une boucle). Alors avant d'avoir à en gérer 101...
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit.
Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant.
Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation.
Dr. Adrian Rogers, 1931
Sve@r est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h14.


 
 
 
 
Partenaires

Hébergement Web