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 :

utilisation de getopts


Sujet :

Shell et commandes GNU

  1. #1
    Membre éclairé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Par défaut utilisation de getopts
    Salut à tous,
    je souhaite utiliser la fonction getopts pour parser les options.
    J'ai dans mon script, une fonction et un programme principal, le programme principal utilise getopts pour effectuer le bon appel fonction (je suis dans un cas ou une option est utilisée à la fois).

    Le problème semble se situer au niveau de la fonction avec getopts puisque aucune des options que j passe ne rentre dans le case et la commande que je construis est vide ...

    le code :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #!/bin/bash -x
     
    #make a pseudo top on pbs jobs.
    top_pbs()
    {
        optstring=u:i:
        while getopts $optstring opt
        do
            echo "!!! $opt !!!"
            case $opt in
                u) echo 'uuu'; cmd="qstat -u $OPTARG" ;;
                i) cmd="qstat $OPTARG" ;;
                *) cmd="qstat -a" ;;
            esac
        done
     
        while (true)
        do
            echo cmd : $cmd
            echo "---"
            eval "$cmd"
            sleep 2
            echo "***"
            clear
        done
    }
     
     
     
    #main
    optstring=mu:i:
    while getopts $optstring opt
    do
        echo "process options"
       case $opt in
          u) echo "uuser" ; top_pbs -u $OPTARG ;; ## $OPTARG contains the argument to the option
          m) top_pbs -u $(whoami) ;;
          i) top_pbs -i $OPTARG ;;
          *) exit 1 ;;
       esac
    done
    résultat d'exécution :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    ./script.sh -u benoit+ optstring=mu:i:
    + getopts mu:i: opt
    + echo 'process options'
    process options
    + case $opt in
    + echo uuser
    uuser
    + top_pbs -u benoit+ optstring=u:i:
    + getopts u:i: opt
    + true
    + echo cmd :
    cmd :
    + echo ---
    ---
    + eval ''
    + sleep 2
    + echo '***'
    ***
    + clear
    + true
    + echo cmd :
    cmd :
    + echo ---
    ---
    + eval ''
    + sleep 2
    merci d'avance,
    ben

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    81
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 81
    Par défaut
    Salut essayes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    optstring="ui"
        while getopts $optstring opt
        do
            case "$opt" in
                'u') echo 'uuu'; cmd="qstat -u $OPTARG" ;;
               'i') cmd="qstat $OPTARG" ;;
                *) cmd="qstat -a" ;;
            esac
        done

  3. #3
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    Il ne faut pas appeler ta variable "optstring", c'est un mot réservé à getopts.
    Et il te manque un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    shift $(($OPTIND-1))
    sous le case.

  4. #4
    Membre éclairé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Par défaut
    salut FRUiT,
    toujours le même problème :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    #!/bin/bash -x
     
    #make a pseudo top on pbs jobs.
    top_pbs()
    {
        string="u:i:"
        while getopts $string opt
        do
            echo "!!! $opt !!!"
            case opt in
                u) echo 'uuu'; cmd="qstat -u $OPTARG" ;;
                i) cmd="qstat $OPTARG" ;;
                *) cmd="qstat -a" ;;
            esac
            shift $(($OPTIND-1))
        done
     
        while (true)
        do
            echo cmd : $cmd
            echo "---"
            eval "$cmd"
            sleep 2
            echo "***"
            clear
        done
    }
     
     
     
    #main
    string="mu:i:"
    while getopts $string opt
    do
        echo "process options"
        case $opt in
            u) echo "uuser" ; top_pbs -u $OPTARG ;; ## $OPTARG contains the argument to the option
            m) top_pbs -u $(whoami) ;;
            i) top_pbs -i $OPTARG ;;
            *) exit 1 ;;
        esac
        shift $(($OPTIND-1))
    done
    Ma variable cmd n' a pas de valeur quand je fais mon echo, le getopts de la fonction déconne...alors que celui du main est ok....


    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    + string=mu:i:
    + getopts mu:i: opt
    + echo 'process options'
    process options
    + case $opt in
    + echo uuser
    uuser
    + top_pbs -u benoit+ string=u:i:
    + getopts u:i: opt
    + true
    + echo cmd :
    cmd :
    + echo ---
    ---
    + eval ''
    + sleep 2
    + echo '***'
    ***
    + clear
    + true
    + echo cmd :
    cmd :
    + echo ---
    ---
    + eval ''
    + sleep 2
    ^C
    une idée ??
    ben

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 133
    Par défaut
    Avec case "$opt" ça fonctionnera peut-être mieux ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  6. #6
    Membre éclairé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Par défaut
    bien vu ,
    c'est toujours pas ça : cmd vide :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #!/bin/bash -x
     
    #make a pseudo top on pbs jobs.
    top_pbs()
    {
        string="u:i:"
        while getopts $string opt
        do
            echo "!!! $opt !!!"
            case "$opt" in
                u) echo 'uuu'; cmd="qstat -u $OPTARG" ;;
                i) cmd="qstat $OPTARG" ;;
                *) cmd="qstat -a" ;;
            esac
            shift $(($OPTIND-1))
        done
     
        while (true)
        do
            echo cmd : $cmd
            echo "---"
            eval "$cmd"
            sleep 2
            echo "***"
            clear
        done
    }
     
     
     
    #main
    string="mu:i:"
    while getopts $string opt
    do
        echo "process options"
        case $opt in
            u) echo "uuser" ; top_pbs -u $OPTARG ;; ## $OPTARG contains the argument to the option
            m) top_pbs -u $(whoami) ;;
            i) top_pbs -i $OPTARG ;;
            *) exit 1 ;;
        esac
        shift $(($OPTIND-1))
    done

    Peut on utiliser gettopts dans une fonction (je ne vois pas pourquoi on ne pourrait pas...) ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 636
    Par défaut
    selon help getopts :
    OPTIND est initialisé à 1 à chaque fois que le shell ou qu'un script shell est appelé

    or, une fonction n'est ni l'un ni l'autre, il faut donc que OPTIND soit local dans la fonction.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Et il me semble que doit être ne dehors du "done", non ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 636
    Par défaut
    exact.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  10. #10
    Membre éclairé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Par défaut
    super réponse (comme d'hab ),
    ça va mieux avec dans ma fonction.
    Peux tu me préciser le rôle exact de l'instruction shift $(($OPTIND-1)) ?
    merci à vous 2
    ben

  11. #11
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 133
    Par défaut
    Il fallait préciser que tu travailles avec bash !
    Avec ksh, il n'est pas nécessaire de réinitialiser OPTIND dans les fonctions.

    OPTIND est une variable mise à jour par getopts qui donne la position de l'élément suivant dans la liste des paramètres. Elle est donc incrémentée à chaque passage dans la boucle while getopts. Si une option comporte un argument, elle est incrémentée de 2 !

    En exécutant shift $(( $OPTIND-1 )), on décale le pointeur de paramètre pour que $1 représente le premier paramètre qui suit la dernière option.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  12. #12
    Membre éclairé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Par défaut
    merci pour ta réponse,
    une question : pourquoi cette instruction n'est pas dans le while, afin de décaler les paramètres à chaque tour de boucle ?

    http://www.linux.com/archive/feed/118031
    When the while loop terminates, we see the next line to be executed is:

    shift $(($OPTIND - 1))

    which is a shift statement used to move the positional parameters of the shell script from $1, $2, etc. down a given number of positions (tossing the lower ones). The variable $OPTIND is an index into the arguments that getopts uses to keep track of where it is when it parses. Once we are done parsing, we can toss all the options that we've processed by doing this shift statement. For example, if we had this command line:

    myscript -a -b alt plow harvest reap

    then after parsing for options, $OPTIND would be set to 4. By doing a shift of three ($OPTIND-1) we would get rid of the options and then a quick echo$* would give this:

    plow harvest reap

    So, the remaining (non-option) arguments are ready for use in your script (in a for loop perhaps). In our example script, the last line is a printf showing all the remaining arguments.

  13. #13
    Membre expérimenté Avatar de FRUiT
    Homme Profil pro
    Inscrit en
    Février 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2011
    Messages : 83
    Par défaut
    Parce que OPTIND représente le nombre total des options et leurs paramètres. C'est écrit dans ta citation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    myscript -a -b alt plow harvest reap
             1  2  3   4    5       6
    OPTIND vaut 4, donc shift $(($OPTIND-1)) enlève les trois premiers arguments de la ligne de commande, afin de laisser les arguments qui ne correspondent pas aux options (cad plow, harvest et reap, qui sont des arguments supplémentaires à passer au script)

    Après analyse des options la ligne de commande devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myscript plow harvest reap
    Donc $1 devient plow, $2 harvest, etc...

    Comme c'est un shift de 3 positions à la fois (et non une) il ne faut pas l'inclure dans le while, my bad.

    [EDIT] Petite précision, dans l'exemple donné, alt est supposé être le OPTARG de l'option b, ce qui n'est précisé nulle part (du moins dans la partie que tu cites), donc les arguments "supplémentaires" commencent après.

  14. #14
    Membre éclairé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Par défaut it works !
    ok ça roule pour moi : merci pour vos supers réponses.
    Je mets un petit bout de code à moi qui m'a permis de bien fixer les choses :
    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
    16
    17
     
    #/bin/bash
     
    #process options
    optstring="a:b:c:d"
    while getopts $optstring opt
    do
        echo "optind :$OPTIND"
        case $opt in
            a) echo "option a" ;;
            b) echo "option b" ;;
            c) echo "option c" ;;
        esac
    done
    echo "\$1 : $1"
    shift $(($OPTIND-1))
    echo "\$1 : $1"
    voici le résultat d'execution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ./scripts/opt.sh -a lolo -b momo -c roro -d lolo
    optind :3
    option a
    optind :5
    option b
    optind :7
    option c
    optind :8
    $1 : -a
    $1 : lolo
    $OPTIND est initialisé à 1
    puis +2 avec : -a lolo
    puis +2 avec : -b momo
    puis +2 avec : -c roro
    puis +1 avec : -d

    Le shift permet de recaler les options pour traiter l'argument lolo.
    merci à tous,
    à bientôt,
    ben

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. utilisation de getopt
    Par cobra150 dans le forum Linux
    Réponses: 2
    Dernier message: 05/12/2011, 16h27
  2. utilisation de getopt
    Par cobra150 dans le forum C
    Réponses: 0
    Dernier message: 04/12/2011, 19h12
  3. [ksh] Problème d'utilisation avec getopts
    Par 1Breton dans le forum Applications et environnements graphiques
    Réponses: 0
    Dernier message: 13/08/2007, 12h13
  4. utilisation de getopt dans le shell
    Par floreasy dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 22/06/2007, 21h34
  5. C : utilisation de getopt - il boucle sans fin...
    Par moussmouss dans le forum C
    Réponses: 14
    Dernier message: 21/12/2005, 11h35

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