Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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