Précédent   Forum des professionnels en informatique > Systèmes > Linux > Applications > Shell
Shell Vos questions sur l'utilisation des commandes shell
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/05/2011, 11h00   #1
Membre éprouvé
 
Avatar de ben.IT
 
Homme Benoît
Inscription : janvier 2009
Messages : 392
Détails du profil
Informations personnelles :
Nom : Homme Benoît
Âge : 24
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : janvier 2009
Messages : 392
Points : 438
Points : 438
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 :
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 :
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
__________________
Meet the free software gang
ben.IT est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2011, 11h34   #2
Nouveau Membre du Club
 
Inscription : avril 2010
Messages : 49
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 49
Points : 37
Points : 37
Salut essayes :

Code :
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
Cj_Dal est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 18/05/2011, 12h08   #3
Membre éclairé
 
Avatar de FRUiT
 
Homme
Inscription : février 2011
Messages : 83
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : février 2011
Messages : 83
Points : 326
Points : 326
Il ne faut pas appeler ta variable "optstring", c'est un mot réservé à getopts.
Et il te manque un :
Code :
1
2
 
shift $(($OPTIND-1))
sous le case.
__________________
Neon Suite by FRUiT (kde4.6) http://tinyurl.com/yzm7cee
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
FRUiT est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/05/2011, 13h55   #4
Membre éprouvé
 
Avatar de ben.IT
 
Homme Benoît
Inscription : janvier 2009
Messages : 392
Détails du profil
Informations personnelles :
Nom : Homme Benoît
Âge : 24
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : janvier 2009
Messages : 392
Points : 438
Points : 438
salut FRUiT,
toujours le même problème :
Code :
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 :
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
__________________
Meet the free software gang
ben.IT est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2011, 14h15   #5
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 445
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 445
Points : 7 532
Points : 7 532
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
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/05/2011, 14h32   #6
Membre éprouvé
 
Avatar de ben.IT
 
Homme Benoît
Inscription : janvier 2009
Messages : 392
Détails du profil
Informations personnelles :
Nom : Homme Benoît
Âge : 24
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : janvier 2009
Messages : 392
Points : 438
Points : 438
bien vu ,
c'est toujours pas ça : cmd vide :
Code :
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...) ?
__________________
Meet the free software gang
ben.IT est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2011, 14h38   #7
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 070
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 070
Points : 4 153
Points : 4 153
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_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/05/2011, 14h51   #8
Expert Confirmé
 
Inscription : janvier 2011
Messages : 970
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : janvier 2011
Messages : 970
Points : 2 871
Points : 2 871
Salut,

Et il me semble que doit être ne dehors du "done", non ?
__________________
$ man woman
Il n'y a pas de page de manuel pour woman.
zipe31 est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/05/2011, 14h56   #9
Expert Confirmé Sénior
 
Avatar de N_BaH
 
Inscription : février 2008
Messages : 2 070
Détails du profil
Informations forums :
Inscription : février 2008
Messages : 2 070
Points : 4 153
Points : 4 153
exact.
N_BaH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/05/2011, 15h24   #10
Membre éprouvé
 
Avatar de ben.IT
 
Homme Benoît
Inscription : janvier 2009
Messages : 392
Détails du profil
Informations personnelles :
Nom : Homme Benoît
Âge : 24
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : janvier 2009
Messages : 392
Points : 438
Points : 438
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
__________________
Meet the free software gang
ben.IT est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2011, 15h59   #11
Modérateur
 
Avatar de al1_24
 
Homme Alain
Ingénieur d'études décisionnel
Inscription : mai 2002
Messages : 4 445
Détails du profil
Informations personnelles :
Nom : Homme Alain
Âge : 51
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études décisionnel
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 4 445
Points : 7 532
Points : 7 532
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
al1_24 est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 18/05/2011, 17h21   #12
Membre éprouvé
 
Avatar de ben.IT
 
Homme Benoît
Inscription : janvier 2009
Messages : 392
Détails du profil
Informations personnelles :
Nom : Homme Benoît
Âge : 24
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : janvier 2009
Messages : 392
Points : 438
Points : 438
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
Citation:
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.
__________________
Meet the free software gang
ben.IT est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/05/2011, 17h32   #13
Membre éclairé
 
Avatar de FRUiT
 
Homme
Inscription : février 2011
Messages : 83
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Paris (Île de France)

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

Code :
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 :
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.
__________________
Neon Suite by FRUiT (kde4.6) http://tinyurl.com/yzm7cee
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean
FRUiT est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/05/2011, 10h32   #14
Membre éprouvé
 
Avatar de ben.IT
 
Homme Benoît
Inscription : janvier 2009
Messages : 392
Détails du profil
Informations personnelles :
Nom : Homme Benoît
Âge : 24
Localisation : France, Puy de Dôme (Auvergne)

Informations forums :
Inscription : janvier 2009
Messages : 392
Points : 438
Points : 438
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 :
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 :
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
__________________
Meet the free software gang
ben.IT est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 14h31.


 
 
 
 
Partenaires

Hébergement Web