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

Scripts/Batch Discussion :

Howto- Gestion des erreurs en scripting de commandes NT (partie 1)


Sujet :

Scripts/Batch

  1. #1
    Membre Expert
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Par défaut Howto- Gestion des erreurs en scripting de commandes NT (partie 1)
    Salut,

    REMARQUE: tous les exmples sont testés dans un XPSP2



    ERRORLEVEL est une variable interne elle indique l'état d'exécution de la dernière opération. Cette variable Contient le code de sortie du dernier programme Windows exécuté.
    Elle fait partie des quelques variables dynamiques "non-caché" généré par le shell:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    >> set /? | findstr /b "%"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    %CD% - se développe en la chaîne du répertoire en cours.
    %DATE% - se développe en la date actuelle en utilisant le même
    %TIME% - se développe en l'heure en cours en utilisant le même
    %RANDOM% - se développe en un nombre aléatoire compris entre 0 et 32767.
    %ERRORLEVEL% - se développe en la valeur en cours de ERRORLEVEL
    %CMDEXTVERSION% - se développe en le numéro de version des
    %CMDCMDLINE% - se développe en la ligne de commande originale

    1) reinitialiser l'ERRORLEVEL "GLOBAL":


    une des difference majeur entre un fichier d'extension .cmd et d'extension .bat et que le dernier ne reinitialise toujours pas l'ERRORLEVEL s'il rencontre l'une des commandes internes suivantes: PATH - APPEND - PROMPT - SET - ASSOC:

    on va prendre un petit exemple, on va essayer d'essayer le premier choix vide puis on va mettre une chaine dans le deuxieme choix:

    Dans le cas d'un '.bat' si on laisse notre choix vide l'errorlevel sera à "1" et même si dans notre deuxieme saisi on tape une chaine, l'errorlevel restera toujours à "1":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    >> type c:\scripts\init.bat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    @echo off
    Set /p a=
    echo  %errorlevel% 
    Set /p b=
    echo  %errorlevel% 
    pause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >> c:\scripts\init.bat
    
     1
    hello
     1
    pour contourner se problème on peux utiliser differentes techniques l'une d'elles est de forcer l'ERRORLEVEL à se reinitialiser "GLOBALEMENT":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >> type c:\scripts\init2.bat
    
    @echo off
    Set /p a=
    echo  %errorlevel% 
    cd.>nul
    Set /p b=
    echo  %errorlevel% 
    pause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >> c:\scripts\init2.bat
    
     1
    hello
     0
    c'est dans ce cas qu'intervient l'extension '.cmd' pour corriger ce petit bug:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >> type c:\scripts\init.cmd
    
    @echo off
    Set /p a=
    echo  %errorlevel% 
    Set /p b=
    echo  %errorlevel% 
    pause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >> c:\scripts\init.cmd
    
     1
    hello
     0

    2) reinitialiser l'ERRORLEVEL de maniere Non-globale:


    l'extension '.cmd' n'a pas resolu entierement le problème de la l'auto-reinitialisation de l'ERRORLEVEL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >> type c:\scripts\initbloc.bat
    
    @echo off
    
    :: && ^
    (
     echo NO ERROR
     BREAK
     REM.) || (
     echo ERROR
    )
    pause

    le REM. va remettre l'errorlevel 0 (dans le bloc) essayez de l'enlever pour voir la différence.

    3) errorlevel après une redirection:

    après une redirection l'errorlevel ne se reinitialise pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >> type c:\scripts\initredir.bat
    
    @echo off
    
    commandnotfound 2>Nul
    echo %errorlevel%
    
    type nul > 3:\fichier.txt
    echo %errorlevel%
    
    pause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >> c:\scripts\initredir.bat
    
    9009
    Le chemin d'accès spécifié est introuvable.
    9009
    pour palier à ce problème on peux utiliser l'opérateurs "||"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >> type c:\scripts\initredir2.bat
    
    @echo off
    
    commandnotfound 2>Nul
    echo %errorlevel%
    
    type nul > 3:\fichier.txt || echo KO
    echo %errorlevel%
    pause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >> c:\scripts\initredir2.bat
    
    9009
    Le chemin d'accès spécifié est introuvable.
    KO
    1
    4) retardé l'expansion de l'errorlevel:

    lorsqu'on execute une boucle Forindo une autre instance CMD s'execute dans le contexte de la ligne de commande, ceci peux causer quelques problèmes, l'une d'elles est que la variable ERRORLEVEL n'est plus visibles dans la portée parente (contexte du batch):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >> type c:\scripts\delayederror.bat
    
    @echo off
    for /f "delims=" %%a in ('"(commandnotfound & echo %ERRORLEVEL%) 2>Nul"') do Set ERROR=%%a
    
    echo %ERROR%
    pause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >> c:\scripts\delayederror.bat
    0
    pour que capturer l'errorlevel de la commande executer dans la boucle forindo on peux soit:

    * utiliser un fichier temporaire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >> type c:\scripts\delayederror2.bat
    
    @echo off
    ( 
     commandnotfound
     call echo %%ERRORLEVEL%%
    ) > error.tmp 2>nul
    for %%i in (type del) do (
     for /f "delims=" %%a in ('%%i error.tmp') do SET ERROR=%%a
    )
    
    echo %ERROR%
    pause

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >> c:\scripts\delayederror2.bat
    9009

    ou bien capturé notre errorlevel puis retardé sa reinitialisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >> type c:\scripts\delayederror3.bat
    
    @echo off
    for /f  %%a in ('%Comspec% /v /c "commandnotfound&echo ^!errorlevel^!" 2^>Nul') do (
       SET ERROR=%%a
    )
    
    echo %ERROR%
    pause
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >> c:\scripts\delayederror3.bat
    9009
    on utilise des carets "^" autour de la variable Errorlevel comme une astuce pour afficher le contenu de la variable dans le contexte de la boucle forindo, en fait, l'execution de la boucle se fait en une seul fois comme est le cas pour tout bloc de code, et ceci ne permetera pas à la variable d'afficher son vrai contenu, donc on initialise notre instance cmd explicitement en activant l'expansion retardé de variables "%COMSPEC% /V" puis on echappe nos "!" par des carets "^!" pour "s'echapper" du contexte de la boucle (execution en une seul fois) et laisser, ainsi, le temps à notre ERRORLEVEL de s'executer.


    5) utilisation de l'operateur "||":

    cet operateur est utiliser conjointement avec l'operateur "&&", il doit etre toujours après l'operateur "&&" sinon toute l'expression sera evalué
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >> type c:\scripts\op.bat
    
    2>Nul commandnotfound ||echo KO && echo OK
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >> c:\scripts\op.bat
    KO
    OK
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >> type c:\scripts\op2.bat
    
    2>Nul commandnotfound && echo OK || echo KO
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >> c:\scripts\op2.bat
    KO
    cet operateur est concus pour traiter les erreurs d'une maniere simple, si la commande retourne une errolevel 1 ou + l'expression à droite de l'expression sera executé et l'ERRORLEVEL sera reinitialiser à 0, c'est super vous dite, mais que faire si une commande peux retourné plusieurs ERRORLEVEL comme c'est le cas pour XCOPY par exemple ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >> type c:\scripts\op3.bat
    
    @echo off
    2>Nul >Nul  xcopy 8:\ 9:\  || echo ERREUR %ERRORLEVEL%
    ECHO %ERRORLEVEL%
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >> c:\scripts\op3.bat
    ERREUR 0
    4
    comme vous pouvez le voir l'operateur "||" ne permet pas une gestion complexe de l'ERRORLEVEL.

  2. #2
    Membre Expert
    Avatar de sachadee
    Homme Profil pro
    AMI DU BAT
    Inscrit en
    Janvier 2013
    Messages
    1 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Brésil

    Informations professionnelles :
    Activité : AMI DU BAT
    Secteur : Distribution

    Informations forums :
    Inscription : Janvier 2013
    Messages : 1 478
    Par défaut
    Merci I'm Here pour ces excellentes explications.


Discussions similaires

  1. [OL-2010] Gestion des erreurs dans un script VBA
    Par sebastian37 dans le forum Outlook
    Réponses: 1
    Dernier message: 08/07/2011, 20h31
  2. Réponses: 9
    Dernier message: 24/11/2008, 13h11
  3. commande shell avec gestion des erreurs
    Par nymus7 dans le forum Programmation et administration système
    Réponses: 0
    Dernier message: 06/08/2008, 13h59
  4. [AIX] Gestion des erreurs dans un script
    Par f-k-z dans le forum AIX
    Réponses: 2
    Dernier message: 17/07/2007, 08h45
  5. Gestion des erreurs sur une commande multiple
    Par domiq44 dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 05/10/2006, 15h03

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