IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Fonction avec getopts ne s'exécute qu'une seule fois


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Fonction avec getopts ne s'exécute qu'une seule fois
    Salut salut!

    J'ai un petit problème! Je suis en train d'essayer d'apprendre à écrire des scripts bash et j'en ai fait à la pelle pour m'entraîner, du générateur de galerie qui crée un fichier html avec mes images miniaturisées, aux créateurs d'ASCII art... j'ai réussi à tout faire fonctionner sans trop de problème, alors je les ai mis dans un fichier définissant une fonction "xxx" et qui est sourcée via mon .bashrc. En gros mon fichier ressemble à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    function xxx {
        local variablesLocales=0 
        ....
     
        while getopts ":abcdef-:" opt; do
            case $opt in
                z ) opt_z=1 ;;
                ....
            esac
     
     
        done
     
    }
    ...et j'ai dans mon bashrc un simple :

    Je ne vous met pas le fichier complet parce que sinon ça s'étalera sur presque 400 lignes, mais si besoin de vous envoie le tout!
    Mon problème, c'est qu'un appel du type "xxx -z param" ne fonctionne qu'une seule fois par terminal... si je veux relancer une nouvelle fois ma fonction, il faut que j'en ouvre un nouveau. C'est assez énervant parce qu'en plus des algos pour m'entraîner j'ai regroupé pas mal de scripts utiles dans ma fonction que j'appelle via des paramètres différents, du coup j'ai souvent besoin de les appeler à la suite (ou parfois plusieurs fois chacun).

    Est-ce que quelqu'un peut m'expliquer le problème et comment le résoudre ?
    Merci beaucoup!

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 539
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 539
    Points : 19 361
    Points
    19 361
    Par défaut
    bonjour,

    il manque un shift après la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    xxx () {
       local var...
       while getopts
    ...
       done
       shift $((--OPTIND))
    }
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Salut, merci pour ta réponse mais mon script contient bien le shift $((OPTIND - 1)) (en plus de l'initialisation de OPTIND à 0 au tout début). Le problème est causé par quelque chose d'autre, une autre idée ? Est-ce que vous arrivez d'habitude à exécuter plusieurs fois vos scripts sourcés sans problème?

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 539
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 539
    Points : 19 361
    Points
    19 361
    Par défaut
    mon script contient bien le shift $((OPTIND - 1)) (en plus de l'initialisation de OPTIND à 0 au tout début)
    ah, bon ? où ça ?
    dans la définition de la fonction ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par yzoug Voir le message
    Mon problème, c'est qu'un appel du type "xxx -z param" ne fonctionne qu'une seule fois par terminal... si je veux relancer une nouvelle fois ma fonction, il faut que j'en ouvre un nouveau.
    Pourrais-tu être plus précis?
    Qu'est-ce qui te fait dire que "ça ne fonctionne qu'une seule fois par terminal"?
    Que se passe-t-il effectivement?
    Y a-t-il un message d'erreur?
    Perds-tu la main dans le terminal?
    La fenêtre terminal se ferme-t-elle?

    De ta réponse dépendra la nôtre...

    Au fait, sous quel environnement es-tu (quel OS, quel terminal, quel shell)?

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    @ N_BaH : non non dans le corps de la fonction, juste après l'initialisation des variables locales j'ai un OPTIND=0 et mon shift est au même endroit où tu l'as mis

    @ jack-ft : je n'ai absolument aucun message d'erreur et le terminal ne se ferme pas, je reprends la main immédiatement après ma commande. Il se passe exactement la même chose que si je fais un ls dans un dossier vide par exemple. Mon script ne s'exécute tout simplement pas. Et quand j'ouvre un nouveau terminal, l'exacte même commande fonctionne comme prévu. Je suis sous Lubuntu 14.10 et j'utilise bash via LXTerminal.

    Je ne vois absolument pas où peut bien être le problème hahah

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par yzoug Voir le message
    @ jack-ft : je n'ai absolument aucun message d'erreur et le terminal ne se ferme pas, je reprends la main immédiatement après ma commande. Il se passe exactement la même chose que si je fais un ls dans un dossier vide par exemple. Mon script ne s'exécute tout simplement pas. Et quand j'ouvre un nouveau terminal, l'exacte même commande fonctionne comme prévu. Je suis sous Lubuntu 14.10 et j'utilise bash via LXTerminal.
    Hmmm.
    Tu récupères bien la main? Si tu fais juste un echo coucou, ça marche?

    Que se passe-t-il si tu tapes typeset -f xxx dans le "vieux" terminal?

    Que se passe-t-il si tu tapes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typeset -ft xxx
    xxx -z param
    Si xxx ne s'exécute pas en mode trace, tu peux aussi essayer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    set -x
    xxx -z param
    set +x

  8. #8
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 539
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 539
    Points : 19 361
    Points
    19 361
    Par défaut
    est-ce que tu démarres un nouveau terminal entre chaque tentative ? histoire de réinitialiser la déclaration de la fonction...

    EDIT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ maFonc() { while getopts abc opts; do case $opts in a) echo a;; b) echo b;; c) echo c;; *) echo err;; esac; done;}
    $ maFonc -a 
    a
    $ maFonc -a
    $ maFonc -a 
    $ maFonc -a
    ah, bah ! mon vélo !?
    Code sans changer terminal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ maFonc() { while getopts abc opts; do case $opts in a) echo a;; b) echo b;; c) echo c;; *) echo err;; esac; done; shift $((--OPTIND));}
    $ maFonc -a

    Code encore dans le même terminal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ maFonc -a 
    a
    $ maFonc -b 
    b
    $ maFonc -c
    c
    CQFD!
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Salut, désolé pour le petit retard pour répondre!

    @jack-ft: en appliquant les instructions que tu me donnes (la deuxième càd faire set -x puis ma fonction) il y a en effet un problème qui apparaît:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    + xxx -z
    + local varLocales=0
    ...
    + getopts :abcz-: opt
    + shift 2
    + '[' 0 -ne 0 ']'
    + '[' 0 -ne 0 ']'
    ...
    Visiblement le paramètre -z ne vérifie pas la condition qui lui ait dédié et qui lance le bout de code qui doit s'exécuter à ce moment-là, ce qui explique en effet pourquoi le script n'a aucun effet...
    Je ne comprends pas non plus pourquoi j'ai un shift 2 alors que mon appel est sous la forme "xxx -z", ça ne devrait pas être un shift 1 ?
    Je suis perdu haha!

    @N_BaH: justement quand je lance un nouveau terminal il n'y a aucun problème tout fonctionne comme prévu, j'aimerai que ça marche dans le même terminal où je suis (exactement comme l'exemple que tu me donnes) et je ne comprends pas pourquoi je n'y arrive pas

  10. #10
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 539
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 539
    Points : 19 361
    Points
    19 361
    Par défaut
    si mon code très simple fonctionne dans ton terminal, alors c'est qu'il y a quelque chose ailleurs dans ton script qui bug.

    ...400 lignes de code ? télécharge-les en pièce-jointe.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

Discussions similaires

  1. Mon script ne s'exécute qu'une seule fois
    Par Phossoyeur dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 21/02/2013, 13h46
  2. La fonction "getElementById('x').value" ne s'exécute qu'une seule fois ?
    Par Hello_World dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 21/10/2010, 16h51
  3. Réponses: 38
    Dernier message: 02/11/2009, 19h20
  4. Réponses: 8
    Dernier message: 26/10/2006, 17h46
  5. fonction qui s'exécute qu'une seule fois sous Firefox
    Par la.sophe dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 01/03/2006, 11h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo