Script sh

Discutez d'informatique ici !
Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 22 Déc 2013, 19:15

PS: Il est mimi ton nouvel avatar, tu passes en mode bizounours pour Noël ?

uii, c'est la résolution pour l'année prochaine.

ou pas :we:
la vie est une fête :)



Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Déc 2013, 21:18

fatal_error a écrit:uii, c'est la résolution pour l'année prochaine.

ou pas :we:


Tant mieux sinon il aurait fallu appeler un exorciste :ptdr:


J'essaie de faire un test qui se veut pas marcher

J'ai une fonction

Code: Tout sélectionner
estDansTar() {

if [ $# -ne 2 ]
then
   return 1;
fi
for i in `tar -tf $1`
   do
   if [ -d $2 ]
   then
      return 2;
   fi
   if [ `basename $i` = $2 ]
   then
      echo 0;
      return 0;
   fi
done
}


Puis je fais le test suivant

Code: Tout sélectionner
if [ `estDansTar $archive $k` -eq 0 ]


Mais ça bloque

Code: Tout sélectionner
./extraireFichierTar.sh: 49: [: -eq: unexpected operator



Pour simplifier le problème; j'ai effectué le code suivant...et il marche; je ne vois pourtant pas ce qui diffère dans le fond de ce que j'ai fait.
Code: Tout sélectionner
test() {
echo 0;
return 0;
}

if [ `test` -eq 0 ]
then
   echo OK;
fi
exit 0;


Peut être je fais mal l'appel de la fonction avec des paramètres ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 22 Déc 2013, 22:48

non, tu as pas reproduit:
Code: Tout sélectionner
test() {
[B]echo 0;[/B]
return 0;
}


si tu enlèves ton echo, tu as une erreur de syntaxe.
La raison, c'est que eq attend deux opérandes (entier)
left -eq right
toi, tu as right qui vaut 0
mais quand tu appèles ta fonction avec les backsticks, tu fais aucun echo, du coup, t'as left qui est vide.

Tu peux t'en sortir ainsi:
Code: Tout sélectionner
if [ $(estDansTar $archive $k>/tmp/null; echo $?) -eq 0 ]

qui consiste à outputer tout ce qui est "echoé" par estDansTar dans la poubelle, pour juste afficher le code de retour de estDansTar (qui est donné par $?).

Mais bon, autant faire un
Code: Tout sélectionner
estDansTar $archive $k;
if [ $? -eq 0 ]; then..


ps: c'est bien d'avoir essayé de reproduire en simplifiant, maintenant, il faut y arriver ;)
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 22 Déc 2013, 23:31

En réalité ça marche comme je l'ai fait, j'avais oublié de mettre un code de retour par défaut dans la fonction. Ce que je viens de faire.

A présent, lorsque je lance avec un fichier non présent dans l'archive; le programme s'exécute comme il faut.
lorsque je lance avec un fichier présent, il continue de planter.

(Je fais maintenant le "désarchivage" dans la fonction.)

Code: Tout sélectionner
estDansTar() {

if [ $# -ne 2 ]
then
   echo 1;
   return 1;
fi
for i in `tar -tf $1`
   do
   if [ -d $2 ]
   then
      echo 2;
      return 2;
   fi
   if [ -d $i ]
   then
      cd $i;
   fi
   if [ `basename $i` = $2 ]
   then
      
      tar -xf $1 $2;
      echo 0;
      return 0;
   fi
done
echo 3; #cas par défaut fichier mais non présent
return 3;
}


Je fais au préalable un shift de 1 position.

Code: Tout sélectionner
if [ `estDansTar $archive $k` -eq 0 ]
      then
         echo essai;
         estDansTar $archive $k;
      fi


Ici un exemple qui marche bien car tata.txt n'est pas dans l'archive.

Code: Tout sélectionner
./extraireFichierTar.sh test.tar tata.txt
Aucun fichier correspondant extrait


Un exemple qui plante car toto.txt est dans l'archive

Code: Tout sélectionner
./extraireFichierTar.sh test.tar toto.txt
tar: toto.txt : non trouvé dans l'archive
tar: Arrêt avec code d'échec à cause des erreurs précédentes
essai
tar: toto.txt : non trouvé dans l'archive
tar: Arrêt avec code d'échec à cause des erreurs précédentes
0
tar: toto.txt : non trouvé dans l'archive
tar: Arrêt avec code d'échec à cause des erreurs précédentes
essai
tar: toto.txt : non trouvé dans l'archive
tar: Arrêt avec code d'échec à cause des erreurs précédentes
0
tar: toto.txt : non trouvé dans l'archive
tar: Arrêt avec code d'échec à cause des erreurs précédentes
essai
tar: toto.txt : non trouvé dans l'archive
tar: Arrêt avec code d'échec à cause des erreurs précédentes
0


La valeur de retour est bien correcte; le test est passé et on entre dans la fonction; cf l'affichage de essai et du 0 de la fonction.

Mais pour une raison que je ne m'explique pas, le programme boucle 3 fois alors qu'il ne devrait boucler qu'une seule fois sur l'exemple en question. Et par ailleurs il ne semble pas trouver toto dans l'archive alors que le test dans la fonction prouve que le fichier est bien présent dans l'archive.

J'ai tout d'abord pensé que c'était parce que le dossier courant dans l'archive ne contenait pas le fichier; j'ai donc rajouté la condition pour se déplacer dans le dossier au cas échéant dans la fonction...mais même résultat. :mur:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 23 Déc 2013, 02:17

1) Ta fonction s'appele estDansTar. On n'est pas censer faire de desarchivage. Crèes une autre fonction..

2) De même, on s'en fout royalement d'avoir des echo dans la fonction. C'est bien pour debugguer, mais ca devrait pas être la condition pour que ton programme fonctionne correctement :marteau:

3) Checker le nombre d'arguments passés à estDansTar, c'est très discutable. Mieux vaut dire dans les commentaires qu'elle attend deux arguments, et lesquels.

4) if [ `basename $i` = $2 ]
j'ai l'impression qu'on tourne en rond. Depuis plein de postes tu t'entiches à utiliser basename, je sais pas ce que tu fais avec, mais ca a l'air d'être au coup de chance..

5) Ca fait plein de fois mais j'ai jamais rien dit, mais les backsticks c'est naze, c'est pas lisible et si t'as le malheur d'avoir un écran un peu sale (...), tu dois te défoncer les yeux pour les voir. Egalement d'autres inconvénients, tels que les backsticks dans les backsticks...mieux vaut utiliser $()

6) Il ne te reste plus qu'à reproduire en simplifiant les parties inutiles de ton script :)
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 23 Déc 2013, 18:07

Je pense que la façon la plus simple d'aborder le problème serait de ce concentrer sur le "désarchivage".

Sans même parler de script.

En admettant une archive a1.tar

contenant:

f1.txt
dir/f2.txt
dir/f3.txt

En admettant que les données entrées par l'utilisateur soit correcte (le fichier est dans l'archive).


Premier niveau de raffinage: Comment extraire f1.
Second niveau de raffinage comment extraire f2 ou f3.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 23 Déc 2013, 18:43

Code: Tout sélectionner
touch f1.txt
mkdir dir
touch dir/f1.txt
tar -cf arch.tar f1.txt dir/f1.txt
rm -rf f1.txt dir

tar -xf arch.tar f1.txt
tar -xf arch.tar dir/f1.txt
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 23 Déc 2013, 19:15

fatal_error a écrit:
Code: Tout sélectionner
touch f1.txt
mkdir dir
touch dir/f1.txt
tar -cf arch.tar f1.txt dir/f1.txt
rm -rf f1.txt dir

tar -xf arch.tar f1.txt
tar -xf arch.tar dir/f1.txt


Bonsoir; je n'ai pas compris ta commande touch; et la description de la commande ne m'a pas vraiment aidé plus :marteau:
Update the access and modification times of each FILE to the current time.


Vu comme ça je dirais que ça crée un fichier tout simplement.

1 Crées le répertoire dir
2 Crées le fichier f1.txt dans dir
3 crées une archive arch.tar contenant f1.txt et dir/f1.txt
4 rm te sert à supprimer un fichier; mais avec ces options je ne vois pas le but exact.

5 Désarchive f1.txt de arch.tar
6 Désarchive le fichier f1.txt contenu dans dir.


Ce qui voudrait dire que en réalité dans ma fonction je ne peux pas désarchiver un fichier en utilisant simplement le nom du fichier; il me faut son adresse par rapport au répertoire courant.

Donc dans ma fonction c'est en réalité

Code: Tout sélectionner
tar -xf $1 $2


que je devrais remplacer par

Code: Tout sélectionner
tar -xf $1 $i



[se prépare à appuyer sur son bouton envoyer la réponse et anticipe le prochain post de fatal]


fatal aurait dit a écrit:
Ben tu sais ce qu'il te reste à faire: TESTE !!!




Tout de suite :d
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 25 Déc 2013, 12:21

Au passage c'était bien ça ;)

Une petite question:

La commande md5sum fichier.txt est censé afficher l'empreinte du fichier suivi du nom du fichier.

J'ai fait un test comme ça avec deux fichiers de mon archive et il se trouve que l'empreinte des deux fichiers est strictement la même; ces deux fichiers n'ont pas le même nom mais sont tous les deux vides.

Je me demandais si c'était normal ou pas x)

d41d8cd98f00b204e9800998ecf8427e dos/blabla.txt
d41d8cd98f00b204e9800998ecf8427e dos/toto.txt
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 20:24

par Iroh » 25 Déc 2013, 14:02

Salut,

Et si tu fais:
Code: Tout sélectionner
echo -n | md5sum

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 25 Déc 2013, 14:58

En écrivant dans l'un des deux fichiers son empreinte a changé donc je suppose que c'est bon; l'empreinte doit être relative au contenu du fichier.


Il me reste une "erreur" que je n'arrive pas à identifier à l'exécution et que je trouve bizarre.

Code: Tout sélectionner
./md5Tar.sh test.tar
./md5Tar.sh: 13: [: =: unexpected operator
800c1710772cfdc854d88fece18ac267  dos/blabla.txt
d41d8cd98f00b204e9800998ecf8427e  dos/toto.txt



Code: Tout sélectionner
#!/bin/sh

if [ $# -ne 1 ]
then
   echo "Usage $0 archive.tar";
   exit 1;
fi

for k in `tar -tf $1`
do

f=`basename $k`;
g=`echo $f | grep 'txt'`;

   if [ $g = `basename $k` ]
then
   tar -xf $1 $k;
   echo "`md5sum $k`";
fi

done
exit 0;


Le programme tourne quand même mais il me cale une erreur d’opérateur inattendu. Pourtant la syntaxe en sh c'est bien string1 = string2
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Iroh
Membre Relatif
Messages: 374
Enregistré le: 14 Oct 2008, 20:24

par Iroh » 26 Déc 2013, 00:01

Code: Tout sélectionner
   if [ "$g" = `basename $k` ]


Il faut «quote» le "$g".

Pour débugger, exécute le script avec la commande
Code: Tout sélectionner
sh -x scriptname.sh arguments
.

[edit]ou remplacer
Code: Tout sélectionner
#!/bin/sh
par
Code: Tout sélectionner
#!/bin/sh -x

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 6 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite