#1 Le 10/01/2016, à 10:33
- MarcTouchereau
[RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
(titre original)Boucle s'arrete a la premiere iteration lorqu'elle contient un "wget"
Bonjour,
Dans le but de telecharger tous les sujets de concours pour les grandes ecoles d'ingenieur, j'ai ecrit un script qui parcourt pour chaque annee, toutes les filieres presentes et telecharge les sujets.
#!/bin/bash
#Telecharge les pdf des sujets de concours
#On recupere les sujets de concours sur le site sujet-de-concours
###################################################################################
# #
# Fonction pour telecharger #
# #
###################################################################################
sujets-get(){
#Telecharge les pdf des sujets de concours presents sur l'URL en argument.
URL=$1
SITE=$(echo $URL | cut -d / -f 1,2,3)
#Les pdf se trouvent a l'adresse $SITE suivie d'une extension
#On recupere toutes les extensions correspondant aux sujets presents
#sur la page et on les stocke dans un fichier
wget -q "$URL" -O -|grep '<a href="/sujets/'|cut -d \= -f3|cut -d \" -f2 > extensions
#Separateur pour le nom final
S='_'
#On parcourt les epreuves presente sur la page et on les telecharge
for i in $( cat extensions ); do
BANQUE=$(echo $i | cut -d / -f3) #Nom de la banque d'epreuve
ANNEE=$(echo $i | cut -d / -f4) #annee de l'epreuve
FILIERE=$(echo $i | cut -d / -f5) #Nom de la filiere
EPREUVE=$(echo $i | cut -d / -f6) #Nom de l'epreuve
echo $BANQUE$S$ANNEE$S$FILIERE$S$EPREUVE #ce qui donne par exemple centrale_2015_tsi_maths1.pdf
wget "$SITE$i" -O $BANQUE$S$ANNEE$S$FILIERE$S$EPREUVE
done
rm extensions
}
###################################################################################
# #
# Script : parcourt les annees et les filieres et telecharge les sujets #
# #
###################################################################################
URL="http://www.sujets-de-concours.net/"
#Il doit y avoir un moyen plus propre de parcourir les annees mais malheureusement
#la liste des annees n'apparait pas dans le wget de $URL
#Je ne sais pas pourquoi...
ANNEE="annee.php?annee="
ANNEE_F="annee_filiere.php?annee=" #Je sais pas pourquoi mais c'est cette chaine de
#requette qui est utilisee pour l'URL avec les pdf
FILIERE="&filiere="
#On parcourt les annees pour lesquelles il y a eu un concours
for i in `seq 1998 2015`; do
#On liste pour chaque annee les filieres prestentes
#et on les stocke dans un fichier texte
wget -q "$URL$ANNEE$i" -O -|grep "alt"|cut -d \" -f4 > filieres
#On parcourt pour l'annee $i toutes les filieres presentes
for f in $(cat filieres); do
#Telecharge tous les sujets de l'annee $i pour la filiere $f
echo "Downloading $URL$ANNEE_F$i$FILIERE$f"
sujets-get "$URL$ANNEE_F$i$FILIERE$f"
done
rm filieres
done
Le script s'arrete apres avoir telecharger les sujets pour l'annee 1998 sans demarrer 1999.
En remplacant
sujets-get "$URL$ANNEE_F$i$FILIERE$f"
par
echo "$URL$ANNEE_F$i$FILIERE$f"
, le script affiche dans la console toutes les urls sensees etre passee a la fonction de telechargement.
Une maniere de contourner ce probleme serait de lister toutes les URL dans un fichier texte et ensuite de modifier
sujets-get()
pour que la fonction prenne en entree le fichier avec toutes les URLs.
Cependant, je suis curieux de savoir pourquoi utiliser
wget
provoque un arret de la boucle...
Des idees?
Dernière modification par MarcTouchereau (Le 10/01/2016, à 12:36)
Hors ligne
#2 Le 10/01/2016, à 11:16
- pingouinux
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
Bonjour,
Peux-tu préciser quelle est la boucle concernée ? (il y en a 2 contenant wget)
Tu peux placer
set -x
en tête du script pour voir comment sont interprétées les commandes.
Hors ligne
#3 Le 10/01/2016, à 11:19
- Compte anonymisé
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
Bonjour,
j'ai testé chez moi, et j'ai des conflits avec les variables de la fonction et ceux en dehors (qui portent le même nom)
#!/bin/bash
sujets-get(){
SITE=$(echo $1 | cut -d / -f 1,2,3)
S='_'
for i in $(wget -q "$1" -O -|grep '<a href="/sujets/'|cut -d \= -f3|cut -d \" -f2); do
BANQUE=$(echo $i | cut -d / -f3)
ANNEE2=$(echo $i | cut -d / -f4)
FILIERE2=$(echo $i | cut -d / -f5)
EPREUVE=$(echo $i | cut -d / -f6)
echo $BANQUE$S$ANNEE2$S$FILIERE2$S$EPREUVE
wget "$SITE$i" -O $BANQUE$S$ANNEE2$S$FILIERE2$S$EPREUVE
done
}
URL="http://www.sujets-de-concours.net/"
ANNEE="annee.php?annee="
ANNEE_F="annee_filiere.php?annee="
FILIERE="&filiere="
for i in `seq 1998 2015`; do
for f in $(wget -q "$URL$ANNEE$i" -O -|grep "alt"|cut -d \" -f4); do
echo "Downloading $URL$ANNEE_F$i$FILIERE$f"
sujets-get "$URL$ANNEE_F$i$FILIERE$f"
done
done
je me suis permis de simplifier, mais ça fonctionne chez moi.
PS : le problème ne venait pas du wget
Dernière modification par Compte anonymisé (Le 10/01/2016, à 11:24)
#4 Le 10/01/2016, à 11:32
- MarcTouchereau
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
@pingouinux
Il s'agit de la boucle suivante qui ne fait que l'annee 1998 sans demarrer l'iteration pour 1999
for i in `seq 1998 2015`; do
#On liste pour chaque annee les filieres prestentes
#et on les stocke dans un fichier texte
wget -q "$URL$ANNEE$i" -O -|grep "alt"|cut -d \" -f4 > filieres
#On parcourt pour l'annee $i toutes les filieres presentes
for f in $(cat filieres); do
#Telecharge tous les sujets de l'annee $i pour la filiere $f
echo "Downloading $URL$ANNEE_F$i$FILIERE$f"
sujets-get "$URL$ANNEE_F$i$FILIERE$f"
done
rm filieres
done
Merci pour
set -x
je ne connaissais pas.
@Anonyme68
En effet, $URL apparait deux fois : dans la fonction
sujets-get()
et dans les instructions du script. Puisque ce qui se passe dans la fonction et dans le reste du script sont sense etre dans differents scopes, pouquoi peuvent-ils interferer?
Hors ligne
#5 Le 10/01/2016, à 11:48
- Compte anonymisé
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
cela me paraissait étonnant aussi, peut-être que je me trompe mais il y avait des variables avec un contenu étrange.
Quoi qu'il en soit mes modifications semblent fonctionnelles.
#6 Le 10/01/2016, à 12:34
- MarcTouchereau
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
Je relirai mon script dans quelques jours pour voir si une erreur me saute aux yeux.
Merci pour la modification. Je ne l'ai pas encore testee, mon pc est encore occupe a telecharger les sujets en contournant le probleme de la boucle.
Juste a titre informatif ou pour les curieux, voici la solution (tres peu elegante) que j'ai utilise.
#!/bin/bash
#Telecharge les pdf des sujets de concours
#On recupere les sujets de concours sur le site sujet-de-concours
URL="http://www.sujets-de-concours.net/"
ANNEE="annee.php?annee="
ANNEE_F="annee_filiere.php?annee=" #Je sais pas pourquoi mais c'est cette chaine de
#requette qui est utilisee pour l'URL avec les pdf
FILIERE="&filiere="
#Separateur pour le nom final
S='_'
#On parcourt les annees pour lesquelles il y a eu un concours
for i in `seq 1998 2015`; do
#On liste pour chaque annee les filieres prestentes
#et on les stocke dans un fichier texte
wget -q "$URL$ANNEE$i" -O -|grep "alt"|cut -d \" -f4 > filieres
#On parcourt pour l'annee $i toutes les filieres presentes
for f in $(cat filieres); do
#Telecharge tous les sujets de l'annee $i pour la filiere $f
echo "$URL$ANNEE_F$i$FILIERE$f" >> addresses
#sujets-get "$URL$ANNEE_F$i$FILIERE$f"
done
done
#Pour chaque addresse valide, on telecharge les sujets disponible
for a in $( cat addresses ); do
#Les pdf se trouvent a l'adresse $URL suivie d'une extension
#On recupere toutes les extensions correspondant aux sujets presents
#sur la page et on les stocke dans un fichier
wget -q "$a" -O -|grep '<a href="/sujets/'|cut -d \= -f3|cut -d \" -f2 > extensions
#On parcourt les epreuves presente sur la page et on les telecharge
for i in $( cat extensions ); do
BANQUE=$(echo $i | cut -d / -f3) #Nom de la banque d'epreuve
ANNEE=$(echo $i | cut -d / -f4) #annee de l'epreuve
FILIERE=$(echo $i | cut -d / -f5) #Nom de la filiere
EPREUVE=$(echo $i | cut -d / -f6) #Nom de l'epreuve
echo $BANQUE$S$ANNEE$S$FILIERE$S$EPREUVE #ce qui donne par exemple centrale_2015_tsi_maths1.pdf
wget "$URL$i" -O $BANQUE$S$ANNEE$S$FILIERE$S$EPREUVE
done
done
rm filieres extensions addresses
Je passe ce thread en resolu, meme si je ne suis pas 100% sur de comprendre l'erreur dans le premier script.
Merci encore pour votre aide.
Hors ligne
#7 Le 10/01/2016, à 13:12
- Compte anonymisé
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
#!/bin/bash
b()
{
echo $a
}
a=2
b
me renvoi 2
donc les variables sont bien conservées
#8 Le 10/01/2016, à 13:46
- pingouinux
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
Pour compléter la réponse d'Anonyme68, une variable définie dans la fonction ne peut remonter que si la fonction est exécutée dans le shell courant.
Exemple :
#!/bin/bash
b() { echo Dans b a=$a; A=3; } # Fonction exécutée dans le shell courant
c() ( echo Dans c a=$a; A=5; ) # Fonction exécutée dans un sous-shell
a=2
echo A=$A
b; echo A=$A
c; echo A=$A
qui renvoie
A=
Dans b a=2
A=3
Dans c a=2
A=3
Hors ligne
#9 Le 10/01/2016, à 13:51
- MarcTouchereau
Re : [RESOLU]Boucle s'arrete a la premiere iteration lorqu'elle contient...
Ah ! Tu as raison !
En fait il faut specifier que l'on utilise des variables locales dans la fonction pour eviter qu'elles n'interferent avec le reste du script.
Documentation.
Le chapitre "local variables" ce de lien illustre bien le probleme.
Du coup, le probleme est bel et bien resolu et j'aurai decouvert un piege a eviter pour mes futurs scripts.
Hors ligne