Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1549 connectés 

  FORUM HardWare.fr
  Linux et OS Alternatifs
  Codes et scripts

  [RESOLU] Bash : trappage de message

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[RESOLU] Bash : trappage de message

n°996198
madmox
Posté le 30-12-2007 à 03:24:59  profilanswer
 

Bonjour,
 
Voilà je dois tester si un paramètre passé à mon script est de type entier. J'avais pensé utiliser typeset (plutôt qu'un bête case "$1" in...), mais j'ai un problème :

Code :
  1. madmox:~/scripts$ typeset -i NB
  2. madmox:~/scripts$ NB="1a" > /dev/null
  3. bash: 1a: valeur trop grande pour la base (error token is "1a" )
  4. madmox:~/scripts$ NB="1a" 2> /dev/null
  5. bash: 1a: valeur trop grande pour la base (error token is "1a" )


Pourquoi la redirection ne marche pas ??? C'est gênant ce message qui s'affiche.
 
Ensuite, autre problème, sûrement lié :

Code :
  1. madmox:~/scripts$ NB="1a" || echo "Erreur"
  2. bash: 1a: valeur trop grande pour la base (error token is "1a" )
  3. madmox:~/scripts$ NB="1a" && echo "Erreur"
  4. bash: 1a: valeur trop grande pour la base (error token is "1a" )
  5. madmox:~/scripts$ NB="1a" ; echo "Erreur"
  6. bash: 1a: valeur trop grande pour la base (error token is "1a" )


Ici, pourquoi le message "Erreur" ne s'affiche pas, et dans aucun cas ? J'ai vérifié le code de retour de NB="1a", c'est 1 (donc bien une erreur), donc s'il est normal que && na marche pas, les deux autres devraient...
 
Edit: Du coup pour le moment j'utilise la ligne :
 
[[ "$ARG" != *[!0-9]* && "$ARG" != "" ]] || traiterErreur
 
Ça marche bien, mais je voudrais comprendre les erreurs du dessus...


Message édité par madmox le 13-01-2008 à 00:05:28

---------------
"Vous êtes un tel connard que je vous inscris pour l'oscar du plus gros connard de l'univers ! Connard !" S.Marsh...
mood
Publicité
Posté le 30-12-2007 à 03:24:59  profilanswer
 

n°996548
b-max
Posté le 31-12-2007 à 15:34:54  profilanswer
 

Je n'en suis pas sur, mais il me semble que typeset renvois un message sur la sortie d'erreur et non sur la sortie normal, ce qui explique pourquoi elle passe à travers le ">".
Comme une erreur est levée, l'instruction s'arrête...
 
Mais ça reste une hypothèse hein :)

n°996799
madmox
Posté le 01-01-2008 à 21:30:57  profilanswer
 

A priori j'ai indiqué dans mon message précédent que j'avais essayé la redirection de stdout ET stderr ("commande > /dev/null" et "commande 2> /dev/null" )
Donc le problème n'est pas là non ? A moins que j'oublie quelque chose...

n°996881
czh
Posté le 02-01-2008 à 11:49:19  profilanswer
 

Et si tu utilisais grep plutôt pour savoir si c'est un entier ?
 
Edit : je viens de voir ton edit
Heu sinon l'affectation c'est pas une commande (un process indépendant). C'est de l'interprétation bash apparemment, donc la redirection de flux ça doit pas trop marcher dessus. C'est le shell bash lui même qu'il faut configurer avec des options.


Message édité par czh le 02-01-2008 à 12:06:22
n°996899
matafan
Posté le 02-01-2008 à 12:56:51  profilanswer
 

Tout à fais. Celà dit tu peux rediriger le stderr de ton shell avant de lancer la commande, avec un "exec 2>/dev/null". Attention quand même, si tu veux ensuite pouvoir afficher à nouveau stderr, il faut prévoir le coup. Tu peux faire un truc du genre :

exec 3>&2           # On créé le fd 3 pour "sauvegarder" la sortie d'erreur
exec 2>/dev/null    # Maintenant les erreurs ne sont plus affichées
# Tu peux faire tes trucs ici
exec 2>&3           # On restore la sortie d'erreur


Message édité par matafan le 02-01-2008 à 12:59:05
n°996910
madmox
Posté le 02-01-2008 à 13:49:26  profilanswer
 

Citation :

l'affectation c'est pas une commande (un process indépendant)


Ok... voilà donc l'astuce ! Merci.
 
Pour le coup du

Citation :

exec 3>&2
exec 2>/dev/null
# Tu peux faire tes trucs ici
exec 2>&3


j'essaierai pour voir ça m'a l'air pas mal effectivement. Merci pour l'info.
 
En revanche je n'explique pas vraiment

Code :
  1. # madmox:~/scripts$ NB="1a" ; echo "Erreur"
  2. # bash: 1a: valeur trop grande pour la base (error token is "1a" )


qui n'affiche pas le message "Error", mais je suppose que ça vient encore du même problème (le shell arrete l'éxécution de la ligne à l'erreur d'affectation)


Message édité par madmox le 02-01-2008 à 13:54:44
n°998621
sputnick
bip...bip...bip...bip...bi...b
Posté le 06-01-2008 à 20:11:52  profilanswer
 

typeset c'est un peu deprecated, ya declare maintenant :  
 
$ help typeset
typeset: typeset [-afFirtx] [-p] name[=value] ...
     Obsolete.  See `declare'.

n°1000667
p-seeker23
Posté le 11-01-2008 à 15:30:24  profilanswer
 

Bash accepte les entiers sous forme "base#nombre", où base est la base de numération. Cette base est par défaut 10 (quand elle est omise).
 
"n=3;" éuivaut à "n=10#3;"
 
Par exemple, "typeset -i n; n=13#4a45; echo $n" donne 10535.
Ca veut dire que le nombre 4a45 sur la base 13 (c'est à dire écrit avec les "chiffres" 0 1 2 3 4 5 6 7 8 9 a b c) vaut 10535 en décimal.
 
Quand tu tapes NR="1a", tu ne précise pas de base, donc c'est 10 par défaut. Or "a" ne fait pas partie des chiffres de la base 10 (qui sont les chiffres de 0 à 9, dix chiffres). C'est pour cela que bash rale. D'ailleurs il se plaint précisément à propos de la "base".
 
Quant au fait de ne pas passer au "echo", je ne vois pas ce qui t'étonnes ! Quand un script rencontre une erreur, il s'arrête, c'est son comportement naturel.  
C'est peut-être que le fait que tu passe les instruction en ligne de commnde qui te perturbes.
Mais si tu mets "echo $(( 1/0 )); ls" dans fichier "err.sh" et que tu tapes "sh (ou bash ou ksh..) err.sh", tu verras jamais le résultat du "ls" ! Seulement l'erreuer résultant du 1/0 (division par 0).
 

n°1001061
madmox
Posté le 12-01-2008 à 13:42:56  profilanswer
 

Citation :

Bash accepte les entiers sous forme "base#nombre", où base est la base de numération. Cette base est par défaut 10 (quand elle est omise).
 
"n=3;" éuivaut à "n=10#3;"
 
Par exemple, "typeset -i n; n=13#4a45; echo $n" donne 10535.
Ca veut dire que le nombre 4a45 sur la base 13 (c'est à dire écrit avec les "chiffres" 0 1 2 3 4 5 6 7 8 9 a b c) vaut 10535 en décimal.
 
Quand tu tapes NR="1a", tu ne précise pas de base, donc c'est 10 par défaut. Or "a" ne fait pas partie des chiffres de la base 10 (qui sont les chiffres de 0 à 9, dix chiffres). C'est pour cela que bash rale. D'ailleurs il se plaint précisément à propos de la "base".

Ca j'avais saisi... le problème c'est pourquoi le echo ne passe pas avec un enchaînement de commande en ";" ou en "||".
 

Citation :

Quand un script rencontre une erreur, il s'arrête, c'est son comportement naturel.

Je crée 2 scripts tests :
 
test_1.sh

Code :
  1. #!/bin/bash
  2. echo $(( 1/0 )) ; ls


test_2.sh

Code :
  1. #!/bin/bash
  2. echo $(( 1/0 ))
  3. ls


L'éxécution du premier s'arrête effectivement à l'erreur (idem avec un "||" à la place du ";" ). C'est ce que je ne comprends pas bien.
En revanche le 2nd affiche le 'ls'. Donc "Quand un script rencontre une erreur, il s'arrête, c'est son comportement naturel" n'est pas vrai (du moins comme je le comprends), mais le fonctionnement de ";" et "||" est différent d'un simple enchaînement de commandes.
 
De plus, si j'éxécute la commande

Code :
  1. ifconfig interface_bidon ; ls

J'ai bien le résultat du ls qui s'affiche, pourtant la première commande lève une erreur (je n'ai pas d'interface qui s'appelle interface_bidon...). Il y a donc une différence entre certaines erreurs.
 
Je pense surtout que le shell arrête l'éxécution d'une ligne lorsqu'il rencontre une erreur du type "echo $(( 1/0 ))" ou "NB="1a"" (cas du NB entier base 10). Mais comment reconnaître une erreur de ce type d'une autre ? (Ce sont d'ailleurs toutes ces erreurs dont on ne peut rediriger la sortie).


Message édité par madmox le 12-01-2008 à 13:46:04
n°1001093
p-seeker23
Posté le 12-01-2008 à 16:36:05  profilanswer
 

Je n'ai pas été très clair sur la deuxième partie apparamment.
 
Sortir ou pas sur erreur, c'est une décision du développeur du programme !
 
Quant tu tapes "ifconfig bidon; ls", t'es dans bash. Il crée (fork) un processus fils où le binaire /bin/ifconfig tourne.
Quand ifconfig rencontre l'erreur due à "bidon", il s'arrête et sort. Il rend la main à son père (bash), qui passe à l'instruction suivante (ls).
Cette sortie est une décision des dévloppeurs de ifconfig, qui ont décidé que s'i l'interfacce désignée n'existait pas, alors "exit -1" ou "return -1"..
 
Reprenons le même raisonnement avec "echo $((1/0)); ls"
 
Avant d'exécuter le "echo $(( 1/0 ))", bash doit évaluer l'expression "$(( 1/0))" qu'il va passer à /usr/bin/echo lorsqu'il le "forkera". Or, les expressions arithmétiques du type "$(())" sont un "built-in" du bash: il ne va pas créer de fils pour évaluer le "$((1/0))", il le fait lui même. Et il rencontre une erreur (division par 0). Alors il affiche un message d'erreur et ne poursuit pas l'évaluation du reste de la ligne. In ne sort pas  (sinon ton promt disparaîtrait) !
Ce comportement est cette fois une décision des développeurs de bash: bash lit les instructions ligne pas ligne et les exécutes de gauche à droite.
Il se moque des erreurs arrivées au sein de ses fils, mais si c'est lui qui se heurte à une erreur, l'exécution de la ligne en cours s'arrête. C'est comme ça que bash fonctionne ! Et c'est pour ça que le fait d'éclater "echo $((1/0)); ls" en une instruction par ligne le fait passer à la ligne suivante. Il arrête l'exécution de la ligne "echo $((1/0))" dès qu'il rencontre une erreur, mais ne sort pas ! Il passe à la ligne suivante "ls".
Heureusement d'ailleurs, parce que s'il sortait suite à ses erreurs, ton terminal disparaîtrait suite au "NB=1a" par exemple !!
 
Dans "ifconfig bidon; ls", il y a erreur, mais ce n'est pas la sienne ! C'est les développeurs de ifconfig qui ont décidé de sortir (de ifconfig !). Ils auraient pu en décider autrement, mais ça aurait été légèrement gênant !
La décision de sortir uniquement sur un "exit" dans bash (et de ne pas sortir sur erreur) est due à la nature d'interpreteur d'nstruction de celui-ci.
C'est juste une (judicieuse !) décision des développeurs.
 
Donc, pour faire simple, quand c'est au shell lui même de faire le boulot (évaluer une expression comme $((1/0)), effectuer une assignation comme NB="1a", ..), si erreur il y a, c'est son problème. Alors il s'arrête (d'interpréter la ligne en cours, et ne sort pas !).
En revanche, si lerreur survient dans l'un de ses "fils" (comme /bin/ifconfig), c'est le problème du fils. C'est le fils qui s'arrête (ou pas d'ailleurs, si le fils est sh par exemple !), et rend la main au bash (ou pas !), qui poursuit jusqu'à la fin de la ligne en cours (tant qu'il-bash- ne recontre pas d'erreur), ou passe à la ligne suivante s'il a atteint la fin de ligne.
 
J'espère avoir été clair cette fois !
 
PS: Les "fils" sont facilement repérables si tu set l'option x (set -x, set +x pour la désactiver) pour déboguer: les lancements de fils  sont précédés d'un signe +.


Message édité par p-seeker23 le 12-01-2008 à 16:40:53
mood
Publicité
Posté le 12-01-2008 à 16:36:05  profilanswer
 

n°1001165
madmox
Posté le 13-01-2008 à 00:04:51  profilanswer
 

Bon ben avec une réponse pareil, je peux me coucher maintenant... Nan sérieusement merci d'avoir pris le temps c'était super clair et du coup le sujet est résolu ! J'avais juste pas saisi que le bash évaluait lui-même les expressions (je pensais qu'il faisait un fils dans tous les cas).
Voilà merci encore !

n°1001424
fighting_f​alcon
Posté le 14-01-2008 à 08:40:24  profilanswer
 

Mini précision, pour info ...
 

Citation :

Et c'est pour ça que le fait d'éclater "echo $((1/0)); ls" en une instruction par ligne le fait passer à la ligne suivante. Il arrête l'exécution de la ligne "echo $((1/0))" dès qu'il rencontre une erreur, mais ne sort pas ! Il passe à la ligne suivante "ls".


 
ce comportement peut être changé par la syntaxe

Code :
  1. set -e


en début de script
 
Ainsi, à la moindre erreur (qu'il s'agisse de bash [echo $((1/0))] ou d'une autre commande [ifconfig bidon]), l'exécution du script entier s'arrête


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Linux et OS Alternatifs
  Codes et scripts

  [RESOLU] Bash : trappage de message

 

Sujets relatifs
[RESOLU] KDE / Boite à miniatures (ksystray)[Résolu] Pas d'erreurs et pourtant ne se lance pas
[RESOLU] Live USB backtrackscanner et aspirine ( résolu )
bash ./prog => progpas de cron sur une mandriva 2007spring[resolu]
Script Bash : appeler un script avec une chaîne en optionubuntu gusty et virtualbox-ose [résolu]
[RESOLU] CUPS : exporter la configuration ?Transfert fichiers automatique serveur FTP [RESOLU]
Plus de sujets relatifs à : [RESOLU] Bash : trappage de message


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR