Script sh

Discutez d'informatique ici !
Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 14 Déc 2013, 23:34

Bonsoir, j'ai pu avancer dans mon problème; je suis passé par un shift

En revanche j'ai un petit soucis; le script fonctionne si les fichiers passé en paramètres sont dans le répertoire courant

sinon lorsqu'on fait [ -f fichier ] il n'est pas capable de détecter qu'il doit aller regarder dans l'archive plutôt que dans le répertoire local.

Code: Tout sélectionner
debut=0;
val=0;
# cas avec option
if [ $1 = -p ]
then
   for i in `tar -tf $2`
   do
      if [ $debut -eq 0 ]
      then
         shift 2;
         debut=1;
      fi
      for k in $* #on parcourt les paramètres décalés
      do

         if [ -d $k ] #on ne vérifie pas autre chose le fichier n'est pas modifié
         then
            echo "Usage: $k n'est pas un fichier accessible";
            exit 3;
         fi
         if [ -f $k ]
         then
            if [ `basename $i` = $k ]
            then
               echo $i;
               val=`expr $val + 1`;
            fi
         fi
      done
   done
if [ $val -eq 0 ]
then
   echo "Aucun fichier correspondant";
   exit 4;
fi
exit 0; #retour 0 si au moins un fichier correspondant
fi


La solution serait de pouvoir bêtement se déplacer dans l'archive comme dans de simples dossiers; mais cd ne marche pas sur une archive.
De plus, je ne dois pas "désarchivé" dans ce script là.

Techniquement si j'enlève le test; le script fonctionne bien; mais on pourrait imaginer le cas farfelu où l'utilisateur archiverait un dossier avec un nom fichier.txt et là le script ne ferait pas la différence; je pense donc qu'il est nécessaire de faire ce test, pour ça une seule solution il faut bien pénétrer dans l'archive.

J'ai parcouru à peu près toutes les options de la commande tar; mais je n'ai rien trouvé capable de cela.
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 » 15 Déc 2013, 08:53

ce n'est pas clair pour moi
Peux-tu faire un exemple?
la vie est une fête :)

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

par Rockleader » 15 Déc 2013, 12:16

fatal_error a écrit:ce n'est pas clair pour moi
Peux-tu faire un exemple?


Le script s'appelle de cette façon.

script.sh [-p] archive.tar fichier.txt [...]

On a donc l'option -p facultative et une liste de fichier de 1 ou plus.

Dans le morceau de code que je te montre; je teste le cas ou $1 = -p

Code: Tout sélectionner
for i in `tar -tf $2`
va afficher toute l’arborescence de l'archive

dans mon cas mon archive contient un dossier dos contenant deux fichiers.
les différentes valeurs seront donc

dos/
dos/f1.txt
dos/f2.txt


Code: Tout sélectionner
if [ $debut -eq 0 ]
      then
         shift 2;
         debut=1;
      fi


Si on est au premier tour d'itération je décale mes paramètres de deux afin de me retrouver sur mon premier fichier pour travailler.

Code: Tout sélectionner
for k in $* #on parcourt les paramètres décalés
==> les fichiers paramètres


A ce moment là, il faut que je teste si ces fichiers sont bien des fichiers. Admettons que je fasse [ -f $k ] ce test ne sera positif que si le fichier paramètre $k est dans le répertoire courant.

HORS le but est de voir si le fichier est un fichier DANS l'archive. Et là ça coince.


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


si le fichier paramètre donné est dans l'archive.

Mais disons que ce test ne m'assure pas que ce soit des fichiers. Si tu reprends mon exemples de tout à l'heure et que tu remplaces le nom de dossier dos par f3.txt...c'est con ok mais possible, et là ça ferait planter le truc car il me trouverait un fichier en commun alors que c'est un dossier.

Il faut donc bien faire le test.
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 » 15 Déc 2013, 12:33

HORS le but est de voir si le fichier est un fichier DANS l'archive. Et là ça coince.

Tu devrais commencer par là.

Deux majeures questions sont soulevées.
1) si l'utilisateur passe un nom de dossier on fait quoi: on matche le nom dans l'archive? on ignore? on rejette?
2) si l'utilisateur passe un nom, mais qui n'existe pas sur son fs, on fait quoi? on rejette? on tente de matcher les noms de l'archive?

Si tu tentes de matcher les noms de l'archive, comment on match?
Avec tout le nom passé en paramètre, seulement avec le basename?

Tes questions ne sont pas des questions de code, mais des questions d'attente du programme.
la vie est une fête :)

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

par Rockleader » 15 Déc 2013, 13:14

Que veux tu dire par fs ?

1) si l'utilisateur passe un nom de dossier on fait quoi: on matche le nom dans l'archive? on ignore? on rejette?


On rejette mais pour ça il faut arriver à faire le test..donc j'en reviens bien au code =)

Si tu tentes de matcher les noms de l'archive, comment on match?
Avec tout le nom passé en paramètre, seulement avec le basename?


Je regarde si le nom de fichier avec son extension est égal à la chaîne de caractère du basename de l'archive.
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 » 15 Déc 2013, 13:30

Que veux tu dire par fs ?

cherche sur le net. Ou proposes la définition si tu n'es pas sûr.

On rejette mais pour ça il faut arriver à faire le test..donc j'en reviens bien au code =)

non. Tu n'es pas bloqué pour tester les dossiers. S'il passe un nom de dossier, ca veut dire que tu sais que c'est un dossier, ca veut dire que tu sais que le dossier existe sur le fs.

Réciproquement, si tu testes et que le nom passé existe pas en tant que dossier, ca veut dire que soit c'est un fichier, soit c'est un fichier/dossier qui existe pas.

Je regarde si le nom de fichier avec son extension est égal à la chaîne de caractère du basename de l'archive.

et si l'utilisateur a saisi dir1/f3.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 » 15 Déc 2013, 13:59

et si l'utilisateur a saisi dir1/f3.txt ???


Je cherche pas à faire un programme parfait non plus; mon cahier des charges me dit que le script prend des noms de fichiers; pour moi un nom de fichier c'est pas une désignation de fichiers.

Pour fs; je ne trouve pas, j'ai rien là dessus dans mon cours et sur internet je ne trouve aucune référence claire
non. Tu n'es pas bloqué pour tester les dossiers. S'il passe un nom de dossier, ca veut dire que tu sais que c'est un dossier, ca veut dire que tu sais que le dossier existe sur le fs.


Si tu le dis...mais je ne vois pas comment, peut être parce que je ne sais toujours pas ce qu'est ce fs...



Simplifions le problème.

J'ai un paramètre $1 qui est une archive et un paramètre $2 qui est une chaine de caractère quelconque.

Comment faire pour savoir si $2 est un nom de fichier/ou de dossier dans $1 ?
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 » 15 Déc 2013, 14:25

d'abord, fs, ca veut dire fileSystem, ton disque dur en (très) gros..

Simplifions le problème.
J'ai un paramètre $1 qui est une archive et un paramètre $2 qui est une chaine de caractère quelconque.
Comment faire pour savoir si $2 est un nom de fichier/ou de dossier dans $1 ?

toujours faire des exemples, je le fais parce que ca fait 5 postes que tu les accouches pas...mais c'est déjà bien d'avoir pensé à simplifier ton programme, chose que tu devrais toujours tenter de faire.
Code: Tout sélectionner
arch.tar:
 f1.txt
 f4.txt
 dir/
 dir/f2.txt
 dir/f4.txt


Cas à gérer, l'utilisateur peut tenter:
Code: Tout sélectionner
f3.txt
f1.txt
dir
dir/
f2.txt
f4.txt
dir/f2.txt
someOtherPath/f1.txt
someOtherPath/f2.txt


==> quels sont les cas où tu dois dire "ok j'ai trouvé ton entrée dans l'archive."

ce que tu vas faire (en gros) c'est prendre tar -tf arch.tar, récupérer tous les noms, et avec un algorithme qui dépend de ce que tu attend de ton script (==>), comparer les noms avec l'entrée utilisateur
la vie est une fête :)

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

par Rockleader » 15 Déc 2013, 14:55

==> quels sont les cas où tu dois dire "ok j'ai trouvé ton entrée dans l'archive."


Sa marchera avec les cas f1.txt ; f2.txt et f4.txt entré par l'utilisateur. S'il entre un chemin ou un dossier ça doit planter.

ce que tu vas faire (en gros) c'est prendre tar -tf arch.tar, récupérer tous les noms, et avec un algorithme qui dépend de ce que tu attend de ton script (==>), comparer les noms avec l'entrée utilisateur


Je crois que l'on ne s'est pas compris; j'ai déjà fait cela.

Mais ça ne suffit pas : Il se peut que le comparaisons de nom soit bonnes; mais qu'il ne s'agisse pas d'un fichier.

Prend le cas ou dans ton archive tu aurais un dossier et je dis bien un dossier nommé avec une extension.txt on trouverait une correspondance de nom mais ce n'est pas ce qu'on veut.

Je persiste donc à dire que je bloque là dessus:

prendre tar -tf arch.tar, récupérer tous les noms


il faut vérifier que ce nom soit bien un fichier ou un dossier avant de le comptabiliser.
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 » 15 Déc 2013, 15:09

arch.tar:
f1.txt
f4.txt
dir/

As tu testé le cas ou tu nommes ton dossier compressé en .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 » 15 Déc 2013, 16:00

Sauf erreur de ma part ça conduit à un plantage:

Code: Tout sélectionner
tar -tf test2.tar

dos.txt/
dos.txt/blabla.txt
dos.txt/toto.txt

 basename `tar -tf test2.tar`

basename: opérande supplémentaire «dos.txt/toto.txt»
Saisissez «*basename --help*» pour plus d'informations.
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 » 15 Déc 2013, 16:28

tu mélanges tout. Chui désolé d'être sec comme ça, mais il faut vraiment que tu poses les points clairement.

1) comment je fais pour savoir si un des noms retourné par mon archive est un dossier
2) comment je fais pour extraire le basename d'un des noms retournés par l'archive

1) j'y ai déjà répondu. et ca ne conduit pas à une erreur. Ou alors j'attends que tu me prouves que un nom retourné par tar qui est un dossier peut ne pas être suffixé par /.
2) c'est qqch d'assez trivial, je sais même pas ce que tu fais avec basename mais dans les grandes lignes: tu récupères la liste des fichiers de tar -tf, et pour chaque ligne, tu extrais le basename que tu peux comparer avec l'input utilisateur

Code: Tout sélectionner
userFile=$2 #assumes user input is already a basename
fileList=$(tar -tf $archive)
for i in $fileList;do
  fName=$(basename $i)
  if [ "$fName" == "$userFile" ];then
    #you want it, you got it
  fi
done
la vie est une fête :)

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

par Rockleader » 15 Déc 2013, 16:57

Je pense qu'on se comprends pas faut dire je m'exprime très mal j'en suis conscient.


Je reprend mon exemple dans archive.tar tu as

Code: Tout sélectionner
dir.txt/
dir.txt/f1.txt
dir.txt/f2.txt


Cette liste on peut la ré obtenir en faisant:

Code: Tout sélectionner
tar -tf archive.tar


Jusque là nous sommes bien d'accord ?

Si on s'arrêtait là .txt = fichier et / = dossier je suis d'accord avec toi.

Seulement je récupère avec basename le nom final

C'est à dire qu'en appliquant basename on va obtenir:

Code: Tout sélectionner
dir.txt
f1.txt
f2.txt


Ainsi je peux comparer mes chaines de caractères.

Mais il n'empêche que j'obtiens la chaine dir.txt et que je n'ai aucun moyen de savoir si c'est un fichier ou un dossier.

Ou alors j'attends que tu me prouves que un nom retourné par tar qui est un dossier peut ne pas être suffixé par /.


Comme je l'ai dit plus haut il l'est bien suffixé par /
Mais je ne travaille pas directement sur le retour de la commande j'applique basename par dessus et oui le basename supprime le / de fin sauf preuve du contraire pour reprendre ton expression.

Chui désolé d'être sec comme ça


Il n'y a pas de raison; c'est comme ça que les choses évoluent :lol3:

Alors encore désolé si je ne comprends pas ce que tu essais de me faire dire.
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 » 15 Déc 2013, 17:32

Jusque là nous sommes bien d'accord ?

oui

oui le basename supprime le / de fin

dans ce cas là utilises pas basename tout de suite.

Déjà, tu peux simplifier le contexte pour tester la détection du slash et incorper tes changements dans ton script plus tard.
Code: Tout sélectionner
f1="a/dir.txt/"
echo $(basename $f1)

tu t'attends à avoir dir.txt/ et non dir.txt

bon ben par exemple tu regardes si il y a le slash a la fin
Code: Tout sélectionner
echo $f1|grep -E "/$"
la vie est une fête :)

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

par Rockleader » 15 Déc 2013, 18:13

:marteau: Pourquoi je n'ai pas pensé à utiliser un grep avant le basename ! :mur:

Cela parait évident maintenant que tu y as fait allusion.

Par contre je comprends pas pourquoi tu n'as pas simplement mis / dans l'argument du grep au lieu de /$.

Merci pour ta patience !
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 » 15 Déc 2013, 18:28

ben si tu mets juste / tu vas dire que a/test c'est un dossier alors que c'est pas le cas. Tu veux seulement capturer le trailing slash.
la vie est une fête :)

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

par Rockleader » 15 Déc 2013, 18:45

Ah c'est le méta pour fin de ligne c'est vrai !

Oki j'y vois plus clair merci ;)
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 » 22 Déc 2013, 13:16

hello; désolé de revenir sur le sujet.

Maintenant que mes exams sont fini je me replonge là dedans et je suis tombé sur un problème assez gênant.

Lorsque j'utilise mon script de cette façon:

Code: Tout sélectionner
./script -p archive.tar fichier.txt


Il fonctionne bien et me retourne le nom du fichier correspondant s'il est dans l'archive. (je n'ai pas retravaillé en détail ce dont nous avions parlé la dernière fois mais ce n'est pas cela qui m'amène).

Maintenant, si je retire l'option -p j'obtiens ce message d'erreur (le script est quand même parcouru puisque j'ai l'affichage de fin).

Code: Tout sélectionner
tar: Ceci ne ressemble pas à une archive de type « tar »
tar: Arrêt avec code d'échec à cause des erreurs précédentes
Aucun fichier correspondant




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

if [ $1 = -p ]
then
   if [ $# -lt 3 ]
   then
   echo "Usage $0 [-p] archive.tar fichier.txt [...]";   
   exit 1;
   fi
fi

if [ $# -lt 2 ]
then
   echo "Usage $0 [-p] archive.tar fichier.txt [...]";   
   exit 2;
fi

debut=0;
val=0;
# cas avec option
if [ $1 = -p ]
then
   for i in `tar -tf $2`
   do
      if [ $debut -eq 0 ]
      then
         shift 2;
         debut=1;
      fi
      for k in $* #on parcourt les paramètres décalés
      do

         if [ -d $k ] #on ne vérifie pas autre chose le fichier n'est pas modifié
         then
            echo "Usage: $k n'est pas un fichier accessible";
            exit 3;
         fi
            if [ `basename $i` = $k ]
            then
               echo `basename $i`;
               val=`expr $val + 1`;
            fi
      done
   done
if [ $val -eq 0 ]
then
   echo "Aucun fichier correspondant";
   exit 4;
fi
exit 0; #retour 0 si au moins un fichier correspondant
fi
# cas sans option
for i in `tar -tf $2`
   do
      if [ $debut -eq 0 ]
      then
         shift 1; #on décale seulement 1 puisque l'on a pas d'option
         debut=1;
      fi
      for k in $* #on parcourt les paramètres décalés
      do

         if [ -d $k ] #on ne vérifie pas autre chose le fichier n'est pas modifié
         then
            echo "Usage: $k n'est pas un fichier accessible";
            exit 5;
         fi
            if [ `basename $i` = $k ]
            then
               pwd;
               val=`expr $val + 1`;
            fi
      done
   done
if [ $val -eq 0 ]
then
   echo "Aucun fichier correspondant";
   exit 6;
fi
exit 0; #retour 0 si au moins un fichier correspondant
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, 13:48

es-tu sûr de ton test
$1 = -p
d'habitude on met ==
et aussi protèges tes variables : "$1" et non $1

edit: tes copier-coller sont atroces!!
si -p c'est facultatif, alors tu regardes si il y a l'option et tu shiftes. ca te permet de factoriser ton exploration d'archive.
De même ton display de menu, tu fais une fonction help(), et tu l'appeles quand les options ne sont pas correctes.
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, 14:34

fatal_error a écrit:es-tu sûr de ton test
$1 = -p
d'habitude on met ==
et aussi protèges tes variables : "$1" et non $1

edit: tes copier-coller sont atroces!!
si -p c'est facultatif, alors tu regardes si il y a l'option et tu shiftes. ca te permet de factoriser ton exploration d'archive.
De même ton display de menu, tu fais une fonction help(), et tu l'appeles quand les options ne sont pas correctes.


Non; en sh en tout cas c'est bien un seul égal; cf man test.

string1 = string2

J'ai trouvé l'erreur; ça venait bien de mon copier coller; dans le premier test je parcours l'archive dans $2; dans le second aussi alors que $2 est un fichier...il s'agissait de $1 en réalité. :marteau:

Tout va bien donc.

PS: Il est mimi ton nouvel avatar, tu passes en mode bizounours pour Noël ? :lol3:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 9 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