Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Script shell, découper la gestion des options en 2 parties

26 réponses
Avatar
Francois Lafont
Bonsoir à tous,

J'ai écrit toute un série de scripts shell (en l'occurrence c'est du
sh, ie le dash d'une Debian) qui se lancent en ligne de commandes avec
des options --foo --bar etc. Tous les scripts ont une série d'options en
commun et ensuite chacun a en plus des options qui lui sont spécifiques.

Pour la gestion des options en shell, perso j'utilise getopt qui me
va très bien jusque là. Pour un script, j'utilise le schéma classique
que l'on retrouve dans les docs sur getopt, à savoir celui-ci :

-----------------------------------------------------
#!/bin/sh

SCRIPT_NAME=${0##*/}
export LC_ALL=C
export PATH='/usr/sbin:/usr/bin:/sbin:/bin'

print_help () {
cat <<EOF
The syntax is:
$SCRIPT_NAME --common1='<value1>' --common2='<value2>' --foo='<bar>'
EOF
}


options_list='help,common1:,common2:,foo:'

if ! TEMP=$(getopt -o "h" -l "$options_list" -n "$SCRIPT_NAME" -- "$@")
then
echo "Syntax error with $SCRIPT_NAME command." >&2
exit 1
fi

eval set -- "$TEMP"
unset TEMP

while true
do
case "$1" in
--common1)
common1="$2"
shift 2
;;

--common2)
common2="$2"
shift 2
;;

--foo)
foo="$2"
shift 2
;;

--help|-h)
print_help
exit 0
;;

--)
shift 1
break
;;
esac
done

# Et ensuite, j'ai mes variables common1, common2 et foo
# à utiliser dans la suite du script pour que celui-ci
# fasse ce que je veux qu'il fasse...
-----------------------------------------------------

Vous voyez ci-dessus, j'ai deux options --common1 et
--common2 qui sont des options communes à tous mes scripts
et l'option --foo, elle, est spécifique au script. Je simplifie
ici car dans mon cas perso il y a plus que 2 options en commun
et en plus ces options communes nécessitent un petit traitement
a posteriori etc. Bref, autant de code que je suis obligé de
dupliquer d'un script à l'autre. Et dans ce cas, toute modification
au niveau de la gestion des options communes devient pénible à gérer
puisqu'il faut modifier sur chaque script sans se tromper.

Ce que je voudrais, c'est avoir cette arborescence :

mes_scripts/
|-- script1.sh
|-- script2.sh
|
| [etc.]
|
|-- scriptN.sh
`-- share/
`-- common_options.sh

où je factoriserais tout le code en rapport avec les options
communes dans share/common_options.sh et dans chaque script
à la racine je ferais quelque choses comme ça :

-----------------------------------------------------
#!/bin/sh

SCRIPT_NAME=${0##*/}
export LC_ALL=C
export PATH='/usr/sbin:/usr/bin:/sbin:/bin'

# On va sourcer le fichier common_options.sh de sorte
# qu'ensuite on peut bénéficier des variables common1
# et common2 etc.
. ./share/common_options.sh

# Maintenant les variables common1 et common2 sont
# bien définies dans le script.

# Dans la suite du script, on va gérer avec getopt les
# options propres au script et uniquement celles-ci
# (ie l'option --foo dans le cas du script donné en
# exemple ci-dessus).
-----------------------------------------------------

Mon problème est que je n'arrive pas à avoir cela.
Je pensais par exemple faire un getopt dans common_options.sh
qui ne gère que les options communes et un getopt dans chaque
script qui ne gère que les options spécifiques mais ça ne marche
pas car dans common_options.sh le getopt plante car il voit
des options qu'il ne reconnaît pas (forcément puisqu'elles seront
traitées après dans le script appelant). Si getopt avait une option
pour lui dire « les options que tu ne connais pas, mets-les dans un
coin mais ne lève pas d'erreur », je pourrais peut-être m'en sortir
ainsi mais getopt ne possède pas une telle fonctionnalité malheureusement.
Apparemment, quand getopt est appelé il faut lui indiquer toutes
les options, pas seulement un bout, ce qui ne facilite pas le
découpage que je souhaite faire.

Après, peut-être qu'il y a une astuce à laquelle je n'ai pas
pensé. Peut-être une « siouxerie » à base de eval... Je ne sais
pas. En tout cas, je n'ai pour l'instant absolument rien trouvé
qui me permette de factoriser le code au niveau des la gestion
des options communes.

Voilà, j'espère avoir été a peu près clair, si vous avez des idées
je suis preneur. Merci d'avance pour votre aide.

--
François Lafont

10 réponses

1 2 3
Avatar
Benoit Izac
Bonjour,

le 28/03/2014 à 02:42, Francois Lafont a écrit dans le message
<5334d383$0$2380$ :

Si getopt avait une option pour lui dire « les options que tu ne
connais pas, mets-les dans un coin mais ne lève pas d'erreur »



info getopt :
If 'getopt' finds an option character in ARGV that was not included
in OPTIONS, or a missing option argument, it returns '?' and sets
the external variable 'optopt' to the actual option character. If
the first character of OPTIONS is a colon (':'), then 'getopt'
returns ':' instead of '?' to indicate a missing option argument.
In addition, if the external variable 'opterr' is nonzero (which is
the default), 'getopt' prints an error message.


En plus standard :

<http://pubs.opengroup.org/onlinepubs/009695399/utilities/getopts.html&gt;
| If an option character not contained in the optstring operand is found
| where an option character is expected, the shell variable specified by
| name shall be set to the question-mark ( '?' ) character. In this
| case, if the first character in optstring is a colon ( ':' ), the
| shell variable OPTARG shall be set to the option character found, but
| no output shall be written to standard error

Après, je ne suis pas sûr que ça suffise car tu passes aussi des
arguments à tes options.

Deux autres pistes :
1) script.sh --common1 c1 --common2 c2 -- --foo --bar remaining_args
2) passer les arguments communs via des variables d'environements

--
Benoit Izac
Avatar
Francois Lafont
Bonsoir,

Le 28/03/2014 18:43, Benoit Izac a écrit :

Si getopt avait une option pour lui dire « les options que tu ne
connais pas, mets-les dans un coin mais ne lève pas d'erreur »



info getopt :
If 'getopt' finds an option character in ARGV that was not included
in OPTIONS, or a missing option argument, it returns '?' and sets
the external variable 'optopt' to the actual option character. If
the first character of OPTIONS is a colon (':'), then 'getopt'
returns ':' instead of '?' to indicate a missing option argument.
In addition, if the external variable 'opterr' is nonzero (which is
the default), 'getopt' prints an error message.



Alors là, je n'ai vraiment pas compris la citation ci-dessus.
Elle parle de getopt qui retourne '?'. Chez moi, getopt me retourne
la valeur 1 en cas d'option non reconnue et m'affiche « test.sh:
unrecognized option '--aaa' ». D'ailleurs, je ne vois pas trop
comment en shell une commande peut retourner '?'. Je pensais qu'une
commande retournait toujours un entier (entre 0 et 255). Il y a
un truc que je ne pige pas là. Perso, j'ai ça sur ma Debian
Wheezy :

$ getopt -o "h" -l "help,common1:,common2:" -n "test.sh"
-- --common1ªa --common2»b --fooÌc; echo $?
test.sh : option non reconnue « --fooÌc »
--common1 'aaa' --common2 'bbb' --
1

$ getopt -V
getopt de util-linux 2.20.1

En plus standard :

<http://pubs.opengroup.org/onlinepubs/009695399/utilities/getopts.html&gt;
| If an option character not contained in the optstring operand is found
| where an option character is expected, the shell variable specified by
| name shall be set to the question-mark ( '?' ) character. In this
| case, if the first character in optstring is a colon ( ':' ), the
| shell variable OPTARG shall be set to the option character found, but
| no output shall be written to standard error

Après, je ne suis pas sûr que ça suffise car tu passes aussi des
arguments à tes options.



Ah, j'ai mis un peu de temps avant de voir que tu parlais de
getopts (avec s). On est d'accord qu'avec getopts, il n'est pas
possible de définir des options longues ? C'est dommage je trouve.

Deux autres pistes :
1) script.sh --common1 c1 --common2 c2 -- --foo --bar remaining_args



Ah oui, c'est une possibilité. Il y a le côté esthétique qui
me gêne un peu.

2) passer les arguments communs via des variables d'environements



Mettre des variables d'environnement n'est-il pas un peu consommateur
de mémoire ? En effet, je ne l'avais pas précisé mais le contexte est
un peu spécifique. Tous ces scripts sont des plugins (ou checks) au sens
nagios qui seront lancés par un logiciel de supervision. Tout ça pour dire
que les scripts seront lancés très fréquemment par le système (ça peut
monter à ~ 10 exécutions de scripts par seconde). Utiliser des variables
d'environnement ne va-t-il pas demander davantage de ressources au
système ? Il m'a semblé avoir entendu dire ça mais je me trompe peut-être.

--
François Lafont
Avatar
Francois Lafont
Soit dit en passant, par rapport à la commande getopt, quelqu'un
peut-il m'expliquer pourquoi j'ai ceci (sur une Wheezy à jour) :

$ getopt -o 'h' -l 'common1:,common2:' -n test.sh -- --common1¡ --common¢
--common1 'a1' --common1 'a2' --

J'indique via -l que j'accepte les option --common1 et --common2.
Mais je fournis l'option --common1 (ok) et l'option --common qui elle
n'est pas censée être autorisée. Je m'attendais à ce que la commande
m'affiche un message d'erreur me disant que l'option --common n'est
pas acceptée. Pourtant ça passe et en plus la commande inflige à
--common1 la valeur 'a2' alors que j'avais indiqué 'a1" comme valeur.

En revanche j'ai bien :

$ getopt -o 'h' -l 'common1:,common2:' -n test.sh -- --common1¡ --common3¢
test.sh : option non reconnue « --common3¢ » ^^^
--common1 'a1' --

Je ne vois pas pourquoi quand j'indique l'option --common3 j'ai
bien un message d'erreur alors que je n'en ai pas pour --common.
Pour moi, les deux commandes ci-dessus devraient renvoyer une
erreur, non ?

--
François Lafont
Avatar
Benoit Izac
Bonjour,

le 29/03/2014 à 02:19, Francois Lafont a écrit dans le message
<53361fb6$0$2303$ :

Si getopt avait une option pour lui dire « les options que tu ne
connais pas, mets-les dans un coin mais ne lève pas d'erreur »



info getopt :
If 'getopt' finds an option character in ARGV that was not included
in OPTIONS, or a missing option argument, it returns '?' and sets
the external variable 'optopt' to the actual option character. If
the first character of OPTIONS is a colon (':'), then 'getopt'
returns ':' instead of '?' to indicate a missing option argument.
In addition, if the external variable 'opterr' is nonzero (which is
the default), 'getopt' prints an error message.



Alors là, je n'ai vraiment pas compris la citation ci-dessus.



Ne t'inquiète pas, c'est normal. ;-)
C'est la documentation de getopt(3) et non getopt(1)...

Ah, j'ai mis un peu de temps avant de voir que tu parlais de
getopts (avec s). On est d'accord qu'avec getopts, il n'est pas
possible de définir des options longues ? C'est dommage je trouve.



Non. Mais d'un autre coté c'est standard et intégré dans le shell.

Deux autres pistes :
1) script.sh --common1 c1 --common2 c2 -- --foo --bar remaining_args



Ah oui, c'est une possibilité. Il y a le côté esthétique qui
me gêne un peu.

2) passer les arguments communs via des variables d'environements



Mettre des variables d'environnement n'est-il pas un peu consommateur
de mémoire ? En effet, je ne l'avais pas précisé mais le contexte est
un peu spécifique. Tous ces scripts sont des plugins (ou checks) au sens
nagios qui seront lancés par un logiciel de supervision. Tout ça pour dire
que les scripts seront lancés très fréquemment par le système (ça peut
monter à ~ 10 exécutions de scripts par seconde). Utiliser des variables
d'environnement ne va-t-il pas demander davantage de ressources au
système ? Il m'a semblé avoir entendu dire ça mais je me trompe peut-être.



Je ne vois pas en quoi ça consommerait de la mémoire, COMMON1=foo va
utiliser quelque octets mais je ne pense pas que tu sois limité à ce
point. Si tu fait un « env », tu verras que tu en utilises déjà pas mal.
À mon avis, c'est même la plus économe de toutes les solutions
proposées.

--
Benoit Izac
Avatar
Benoit Izac
Bonjour,

le 29/03/2014 à 04:42, Francois Lafont a écrit dans le message
<53364109$0$2050$ :

Soit dit en passant, par rapport à la commande getopt, quelqu'un
peut-il m'expliquer pourquoi j'ai ceci (sur une Wheezy à jour) :

$ getopt -o 'h' -l 'common1:,common2:' -n test.sh -- --common1¡ --common¢
--common1 'a1' --common1 'a2' --

J'indique via -l que j'accepte les option --common1 et --common2.
Mais je fournis l'option --common1 (ok) et l'option --common qui elle
n'est pas censée être autorisée. Je m'attendais à ce que la commande
m'affiche un message d'erreur me disant que l'option --common n'est
pas acceptée. Pourtant ça passe et en plus la commande inflige à
--common1 la valeur 'a2' alors que j'avais indiqué 'a1" comme valeur.

En revanche j'ai bien :

$ getopt -o 'h' -l 'common1:,common2:' -n test.sh -- --common1¡ --common3¢
test.sh : option non reconnue « --common3¢ » ^^^
--common1 'a1' --

Je ne vois pas pourquoi quand j'indique l'option --common3 j'ai
bien un message d'erreur alors que je n'en ai pas pour --common.
Pour moi, les deux commandes ci-dessus devraient renvoyer une
erreur, non ?



Je pense que getopt reconnais les raccourcis : si il voit une option qui
correspond au début des options autorisées, il la substitue, essaye avec
« --cºr », il te donnera « --common1 'bar' ». Par contre common3 n'est
pas une option légale.

--
Benoit Izac
Avatar
Francois Lafont
Le 29/03/2014 11:07, Benoit Izac a écrit :

Je pense que getopt reconnais les raccourcis : si il voit une option qui
correspond au début des options autorisées, il la substitue, essaye avec
« --cºr », il te donnera « --common1 'bar' ». Par contre common3 n'est
pas une option légale.



Ah, ok. Effectivement dans la page man, il est indiqué que l'on peut
utiliser des abréviations des options longues tant que celles-ci ne
sont pas ambiguës. En tout cas, perso si ça ce n'est pas ambigu pour
les dév de getopt :

$ getopt -s sh -o 'h' -l 'common1:,common2:' -n test.sh -- --common1¡ --co¢
--common1 'a1' --common1 'a2' --

où --co peut très bien être une abréviation de --common1 ou de --common2,
alors je me demande bien à quoi pourrait ressembler une abréviation ambiguë
alors.

En fait, la commande getopt doit lire la liste des options longues (de la
gauche vers la droite) et dès qu'une option longue matche avec l'abréviation
il considère que l'abréviation correspond à cette option là. Du coup, si
j'inverse l'ordre de common1 et common2 dans la liste des options longues,
j'obtiens ça :

$ getopt -s sh -o 'h' -l 'common2:,common1:' -n test.sh -- --common1¡ --co¢
--common1 'a1' --common2 'a2' --

Perso, je trouve ce comportement vraiment douteux mais bon...

--
François Lafont
Avatar
Francois Lafont
Bonjour,

Le 29/03/2014 11:02, Benoit Izac a écrit :

info getopt :
If 'getopt' finds an option character in ARGV that was not included
in OPTIONS, or a missing option argument, it returns '?' and sets
the external variable 'optopt' to the actual option character. If
the first character of OPTIONS is a colon (':'), then 'getopt'
returns ':' instead of '?' to indicate a missing option argument.
In addition, if the external variable 'opterr' is nonzero (which is
the default), 'getopt' prints an error message.



Alors là, je n'ai vraiment pas compris la citation ci-dessus.



Ne t'inquiète pas, c'est normal. ;-)
C'est la documentation de getopt(3) et non getopt(1)...



Ah ok.

Ah, j'ai mis un peu de temps avant de voir que tu parlais de
getopts (avec s). On est d'accord qu'avec getopts, il n'est pas
possible de définir des options longues ? C'est dommage je trouve.



Non. Mais d'un autre coté c'est standard et intégré dans le shell.



C'est vrai. Ceci étant, comme tu le disais toi-même dans un précédent
message, getopts ne pourra pas répondre à mon problème (ou alors très
difficilement) car j'utilise des options avec arguments. Et effective-
ment, après réflexions (en supposant que je me limite aux options
courtes), ça me semble bloquant.

2) passer les arguments communs via des variables d'environements



Mettre des variables d'environnement n'est-il pas un peu consommateur
de mémoire ? En effet, je ne l'avais pas précisé mais le contexte est
un peu spécifique. Tous ces scripts sont des plugins (ou checks) au sens
nagios qui seront lancés par un logiciel de supervision. Tout ça pour dire
que les scripts seront lancés très fréquemment par le système (ça peut
monter à ~ 10 exécutions de scripts par seconde). Utiliser des variables
d'environnement ne va-t-il pas demander davantage de ressources au
système ? Il m'a semblé avoir entendu dire ça mais je me trompe peut-être.



Je ne vois pas en quoi ça consommerait de la mémoire,



Ok, j'avais dû lire ça dans "Elle" ou "Figaro Madame". :)

COMMON1=foo va
utiliser quelque octets mais je ne pense pas que tu sois limité à ce
point. Si tu fait un « env », tu verras que tu en utilises déjà pas mal.
À mon avis, c'est même la plus économe de toutes les solutions
proposées.



Ok. Merci pour tes explications Benoît.

Bon, j'ai quand même tenté un ultime essai (voir ci-dessous) qui semble
faire ce que je souhaite mais c'est peut-être un peu tordu.

Qu'en pensez-vous ? Est-ce que ça répond bien au problème ? N'y a t-il
pas des cas où ça peut faire n'importe quoi ? J'ai quelques doutes. Si
ça sent trop le souffre ce machin là, je m'en tiendrai aux variables
d'environnement comme le propose Benoît.

J'ai donc cette arborescence :

mes_scripts/
|-- script1.sh
|-- script2.sh
|
| [etc.]
|
|-- scriptN.sh
`-- share/
`-- common_options.sh

Avec par exemple pour script1.sh :

---------------------------------------------
#!/bin/sh

SCRIPT_NAME=${0##*/}
SPECIFIC_SHORT_OPTIONS='f:,b:'
SPECIFIC_LONG_OPTIONS='foo:,bar'
SPECIFIC_SYNOPSIS="--foo='foo' [ --bar ]"

get_specific_options () {
case "$1" in
-f|--foo)
FOO="$2"
return 2
;;
-b|--bar)
BAR="true"
return 1
;;
esac
return 0
}

. share/common_options.sh

echo "common1: [$COMMON1]"
echo "common2: [$COMMON2]"
echo "foo: [$FOO]"
echo "bar: [$BAR]"
---------------------------------------------

Et dans ./share/common_options.sh, j'ai ça :

---------------------------------------------
export LC_ALL=C
export PATH='/usr/sbin:/usr/bin:/sbin:/bin'

COMMON_SYNOPSIS="--common1='<value1>' --common2='<value2>'"
COMMON_SHORT_OPTIONS='h'
COMMON_LONG_OPTIONS='help,common1:,common2:'

print_help () {
cat <<EOF
The syntax is:
$SCRIPT_NAME $COMMON_SYNOPSIS $SPECIFIC_SYNOPSIS
EOF
}

if ! TEMP=$(getopt -o "$COMMON_SHORT_OPTIONS,$SPECIFIC_SHORT_OPTIONS"
-l "$COMMON_LONG_OPTIONS,$SPECIFIC_LONG_OPTIONS"
-n "$SCRIPT_NAME" -- "$@")
then
echo "Syntax error with $SCRIPT_NAME command." >&2
print_help
exit 1
fi

eval set -- "$TEMP"
unset TEMP

while true
do
case "$1" in
--common1)
COMMON1="$2"
shift 2
;;

--common2)
COMMON2="$2"
shift 2
;;

--help|-h)
print_help
exit 0
;;

--)
shift 1
break
;;

*)
get_specific_options "$1" "$2" || shift "$?"
;;
esac
done
---------------------------------------------

--
François Lafont
Avatar
Benoit Izac
Bonjour,

le 29/03/2014 à 16:28, Francois Lafont a écrit dans le message
<5336e682$0$2077$ :

Bon, j'ai quand même tenté un ultime essai (voir ci-dessous) qui
semble faire ce que je souhaite mais c'est peut-être un peu tordu.

Qu'en pensez-vous ? Est-ce que ça répond bien au problème ?



À vrai dire, je ne sais pas si ça répond au problème car je n'ai pas en
tête d'exemple équivalent à ce que tu souhaites faire. Peux-tu donner un
exemple concret de besoin d'avoir les mêmes options pour plusieurs
programmes ? Quel genre de tâches font ces options ?

Il y a peut-être plus simple à faire qu'une usine à gaz. Dans le cas
contraire, il existe sans doute d'autres langages que le shell qui
peuvent répondre à ton besoin.

--
Benoit Izac
Avatar
Francois Lafont
Le 29/03/2014 21:33, Benoit Izac a écrit :

Bon, j'ai quand même tenté un ultime essai (voir ci-dessous) qui
semble faire ce que je souhaite mais c'est peut-être un peu tordu.

Qu'en pensez-vous ? Est-ce que ça répond bien au problème ?



À vrai dire, je ne sais pas si ça répond au problème car je n'ai pas en
tête d'exemple équivalent à ce que tu souhaites faire. Peux-tu donner un
exemple concret de besoin d'avoir les mêmes options pour plusieurs
programmes ? Quel genre de tâches font ces options ?



En fait, ces scripts sont ce qu'on appelle des "plugins nagios" dans
le jargon de la supervision. Leur synopsis est de cette forme :

check_snmp_truc ( --v2c --community='<comm>' | --secname='<user>'
-x='<authpass>' -X='<privpass>' -L='<authproto,privproto>' )
--host='<address>' ...

Autrement dit, tu as deux types d'appel possibles :

1) check_snmp_truc --v2c --community='<comm>' --host='<address>' ...

ou

2) check_snmp_truc --secname='<user>' -x='<authpass>'
-X='<privpass>' -L='<authproto,privproto>' --host='<address>' ...

Les scripts lancent une requête SNMP à destination d'un hôte (via
l'option --host) sachant que SNMP requiert une sorte d'authentification
par mots de passe sans quoi le serveur interrogé ne répond pas à la
requête. L'authentification se fait via des options à indiquer qui ne
sont pas les mêmes suivant qu'on passe par du SNMP version 2 (cas de
l'appel de 1) ou par du SNMP version 3 (cas de l'appel 2).

Chaque script lance une requête SNMP spécifique lui permettant
d'obtenir une information particulière à propos de l'hôte interrogé.
Par exemple :

- check_snmp_raid permettra connaître l'état du contrôleur RAID des
machines interrogées;
- check_snmp_sensitive_files permettra de vérifier que certains
fichiers sensibles de l'hôte interrogé n'ont pas été modifiés.
- etc. etc.

Tous ces scripts sont stockés sur un serveur de supervision qui possède
une liste de serveurs à interroger (par exemple tous les serveurs d'un
réseau local). Le logiciel de supervision va donc lancer tous ces scripts
à intervalles réguliers sur chacun des hôtes indiqués dans sa base.
Imagine par exemple qu'il y a 20 scripts à lancer toutes les 5 minutes
sur une base de 100 machines, cela fait 2000 exécutions de scripts
en 5 minutes, soit 400 exécutions toutes les minutes. Cela peut vite
être consommateur de mémoire. L'aspect performance n'est donc pas à
négliger.

Comme tu peux voir, tous les scripts ont donc une série d'options en
commun (les options pour l'authentification SNMP v2 ou v3 et l'adresse
de l'hôte à interroger) et c'est la gestion de ces options communes que
je voudrais factoriser à un seul endroit. Pour le reste, chaque script
a sa spécificité.

Ensuite, les « ... » que j'ai mis dans les appels 1) et 2) juste après
l'option --host représentent des options éventuelles qui sont propres
à chaque script. Par exemple si je reprends l'exemple de check_snmp_raid,
on peut imaginer qu'il va nécessiter en plus des options communes l'option
--raid-type='xxx' car suivant le type de contrôleur RAID de l'hôte qu'on
interroge, la requête SNMP à effectuer n'est pas forcément la même.
Mais cette option --raid-type n'existe pas pour check_snmp_sensitive_files
par exemple etc. etc.

Et mon objectif dans tout ça est de pouvoir factoriser dans un
unique fichier la gestion des options communes à tous ces scripts.

Est-ce que c'est plus clair maintenant avec le contexte ?

Il y a peut-être plus simple à faire qu'une usine à gaz. Dans le cas
contraire, il existe sans doute d'autres langages que le shell qui
peuvent répondre à ton besoin.



Actuellement j'ai déjà quelque chose qui tourne à base de shell sh
et c'est vraiment très satisfaisant au niveau perf. En revanche ma
gestion des options n'est pas factorisée ce qui est à l'origine de
mon post ici. Si demain je suis amené à ajouter une option commune
ou bien à en modifier une etc. j'aurai des difficultés.

J'ai bien tenté un portage en Python par exemple avec un truc super
propre au niveau de la gestion des options mais j'ai très vite vu
qu'au niveau perf, ça n'avait plus rien à voir ce qui est assez
logique car avec Python on est dans du plus haut niveau avec de
l'objet etc. et ça a un coût en terme de mémoire forcément. J'ai
essayé, très modestement, le Perl aussi. C'était mieux au niveau
perf que Python mais malgré tout nettement moins bon que le shell sh
dont je dois dire que j'ai été assez bluffé par le faible coût en
terme de mémoire et de cpu. Après il y a le C bien sûr, mais je n'y
connais strictement rien en C. En fait, le shell me convient très bien,
voire parfaitement bien si j'avais la possibilité de factoriser la gestion
des options communes.

Voilà. :)

--
François Lafont
Avatar
Benoit Izac
Bonjour,

le 29/03/2014 à 23:43, Francois Lafont a écrit dans le message
<53374c8d$0$2205$ :

J'ai bien tenté un portage en Python par exemple avec un truc super
propre au niveau de la gestion des options mais j'ai très vite vu
qu'au niveau perf, ça n'avait plus rien à voir ce qui est assez
logique car avec Python on est dans du plus haut niveau avec de
l'objet etc. et ça a un coût en terme de mémoire forcément. J'ai
essayé, très modestement, le Perl aussi. C'était mieux au niveau
perf que Python mais malgré tout nettement moins bon que le shell sh
dont je dois dire que j'ai été assez bluffé par le faible coût en
terme de mémoire et de cpu. Après il y a le C bien sûr, mais je n'y
connais strictement rien en C. En fait, le shell me convient très bien,
voire parfaitement bien si j'avais la possibilité de factoriser la gestion
des options communes.



Désolé mais je ne connais Nagios que de nom, je n'ai jamais pris le
temps de m'y mettre (pas de besoin non plus). En regardant vite fait,
j'ai trouvé ça (Perl) :
<http://www.pplusdomain.net/Writing%20Nagios%20Plugins%20in%20Perl.pdf&gt;
<http://search.cpan.org/~maxschube/Nagios-Plugin-SNMP-1.2/lib/Nagios/Plugin/SNMP.pm&gt;

Si j'ai bien compris un plugin snmp consiste en :
1) faire une requête snmp ou exécuter une commande local
2) analyser la réponse
3) renvoyer sur la sortie standard : état - informations

Pour les perf, à quel niveau est-ce que ça coince ?

--
Benoit Izac
1 2 3