Apprendre la programmation par script batch – Un bon serveur Minecraft

Les fichiers de commandes sont des scripts de commande qui s'exécutent dans l'interpréteur de commandes Windows. Alors, quel pourrait être l’intérêt d’écrire ces lignes de commande dans un script? En fait, il y a plusieurs raisons:

  • évitez de devoir réécrire constamment les mêmes commandes lors de tâches répétitives;
  • Possibilité de créer de vrais petits programmes facilitant les tâches à exécuter via l'interpréteur de commandes.

Nous étudierons des méthodes pour concevoir ces programmes. Dans la suite de ce document, nous utiliserons la convention suivante:

  • les termes interprète de commande ou interprète décrivent l'exécutable cmd.exe;
  • dans les syntaxes de commande, le cadre des pièces avec les caractères [[[[ et ] sont facultatifs, le cadre des pièces avec les caractères < et > sont remplacés par différentes informations à fournir (celles-ci seront précises avec la syntaxe) et les parties encadrées avec les caractères et sont des parties à choix multiples o chaque choix est séparé des autres avec le caractère |.

La convention syntaxique est la même que pour l'aide en ligne de commande, ce qui facilitera votre compréhension.

Sommaire

I-A. L'éditeur de texte ▲

Un simple éditeur de texte, tel que le bloc-notes fourni avec Windows, n’est pas pratique pour écrire des scripts batch. Pour exploiter pleinement les capacités de ces scripts, vous devez être en mesure de coder des caractères non anglais tels que des accents ou 砻 afin d'accéder aux fichiers dont le nom contient ces types de caractères exotiques. La plupart des éditeurs de texte codent les fichiers avec le jeu de caractères ANSI correspondant à la langue d'installation du système d'exploitation, tandis que l'interpréteur de commande utilise un temps de page de code (également appelé Page de code) en tant que CP-850, qui est le codage par défaut de l’interprète pour les systèmes Windows installés en français (France).

Sous Windows, vous disposez peut-être déjà d’un éditeur de texte, le Notepad ++ (la version 5.9.x ou une version ultérieure est nécessaire); si ce n'est pas le cas, vous pouvez le télécharger ici: http://notepad-plus-plus.org/en/

Dans ce dernier cas, vous pourrez sélectionner le codage dans le menu Codage> Codage de caractères, puis si vous voulez le français par exemple: sélectionnez Langues de l'Europe de l'Ouest> OEM-850. Dans Notepad ++, le pages de code sont des appels OEM-XXX, au lieu de CP-XXX, mais ce sont les mêmes codages. Il convient également de noter que dans le même menu que OEM-850, il y a OEM-863: français; c'est français, mais pour le Qubec. Cette manipulation sera effectuée pour que chaque script utilise l'encodage correct. Il n'est pas possible d'effectuer cette opération automatiquement dans Notepad ++.

Bloc-notes ++

I-B. Encodage des caractères ▲

La gestion des pages de code dans l'interpréteur se fait via les commandes mode et chcp, ces commandes sont utilisées pour afficher le page de code utilisé ou le modifier en utilisant l’une des syntaxes suivantes.

Définir les page de code utiliser (o est le nombre de page de code).

mode chatte sélectionnez cp=<XXX>

chcp <XXX>

Voir la page de code utilisé.

mode chatte cp [/status]

chcp

Le tableau 1 fournit une liste non exhaustive des différents pages de code utilisé par l'interpréteur de commandes.

Page de code

La description

CP-437

pour le soutien des langues anglophones.

CP-720

pour le soutien des langues arabes.

CP-737

pour le soutien du grec.

CP-775

pour le soutien des langues baltes.

CP-850

pour la prise en charge des langues d'Europe occidentale (mises à jour par le CP 858), y compris le français (France), mais également l'allemand, le basque, le catalan, le danois, l'espagnol, le finnois, l'italien, le français espagnol, le norvégien, le portugais, le suédois, l'afrikaans, le féroïen, Flamand et irlandais.

CP-852

pour le soutien des langues d'Europe centrale.

CP-855

pour le soutien de l'alphabet cyrillique.

CP-857

pour le soutien du turc.

CP-858

pour le support des langues d'Europe occidentale, y compris le français (France), il s'agit d'une mise à jour 1998 basée sur le CP-850 ou seul le symbole € a été ajouté au point de code 0xD5.

CP-861

pour le soutien de islandais.

CP-863

pour le soutien du français (Qubec).

CP-864

pour le soutien des langues arabes.

CP-866

pour le soutien de l'alphabet cyrillique.

CP-869

pour le soutien du grec.

Tableau 1: page de code

Il convient de noter que, malgré la mise à jour du CP-850 par le CP-858, le codage par défaut de l’interpréteur Windows installé en français (France) reste le CP-850. Il est donc préférable d'utiliser le CP-850. La liste de pages de code supporté par un système Windows est disponible dans le registre sous la clé: HKLM SYSTEM CurrentControlSet Control Nls CodePage. Vous remarquerez la présence de 1252 dans le mentionné précédemment, c'est l'encodage Windows-1252 utilisé par les API Windows et donc par la plupart des ordinateurs portables sur des systèmes installés en français (France); cependant, il n'est pas recommandé de l'utiliser dans l'interpréteur de commandes car les commandes ne sont pas faites pour le prendre en charge, cela peut même causer des bogues dans certains cas. Le codage par défaut pour l'interpréteur peut être trouvé via la valeur OEMCP De type REG_SZ toujours dans ce qui est mentionné ci-dessus.

Il est possible d'ajouter Pages de code manquant (par défaut, seulement pages de code sont disponibles) en installant le pack de langue correspondant au codage souhaité. Chaque module linguistique comprend une table de conversion qui permet à Windows de convertir un point de code en une représentation graphique et de l’afficher. Il est également possible d’utiliser Unicode (UCS-2 uniquement) avec la sortie de commande interne de l’interpréteur pour permettre une interaction avec les programmes utilisant le langage Unicode natif (pour Perl par exemple) en appelant l’interprète via la commande suivante (o est la commande à exécuter).

cmd / u <ordre>

Dans Notepad ++, vous pouvez ajouter les caractères manquants au clavier via le menu Edition> Panneau de caractères ASCII, puis double-cliquez sur le caractère souhaité.

I-C. Bonjour le monde ▲

Nous allons commencer par le monde traditionnel hello, voici le code (Script 1). Copiez le code dans Notepad ++, puis enregistrez-le avec l'encodage OEM-850 et l'extension .bat ou .cmd (uniquement sur les systèmes Vista et supérieurs).

La différence entre le fichier .bat et le fichier .cmd réside dans l'interpréteur de commandes. En fait, sur les systèmes Windows XP, il existait deux interpréteurs de commandes: cmd.exe et COMMAND.COM. Les fichiers avec l'extension .bat ont été gérés par cmd.exe et les fichiers avec l'extension .cmd ont été gérés par COMMAND.COM, les deux types de fichiers ayant des spécificités différentes. Cependant, sous Windows Vista et au-dessus, il ne reste que cmd.exe. Tous les scripts .bat et .cmd sont exécutés par cmd.exe et ont les mêmes spécificités.

1.
2
3
4
5
6
7.
8
9

@écho de
cls




écho Bonjour Monde !!!! Dj l ?
écho.
pause

Lorsque nous exécutons ce script en cliquant dessus, nous obtenons l'affichage suivant.

Script_Hello_World

Regardons la composition du script 1. La première ligne, @Écho off, est déjà intéressant, il est composé:

  • préfixe @ qui sert à inverser l'état de l'affichage standard;
  • de la commande écho qui est utilisé pour gérer l'affichage sur la ligne de commande;
  • et le paramètre de qui sert à désactiver la vue standard.

L’affichage standard définit ce que l’interpréteur de commandes affiche par défaut. Par exemple, lors du lancement de l'interpréteur de commande ci-dessous; la vue standard renvoie le chemin du répertoire en cours, soit C: Utilisateurs Portable>.

STD_Prompt

Lors de l'exécution d'un script, la vue par défaut renvoie, par défaut, le chemin d'accès du répertoire actuel, suivi de l'exécution de la commande, comme dans l'exemple ci-dessous.

Aucune image disponible "width =" 366 "height =" 108

Le préfixe @, lorsqu'il est placé en début de ligne, sert à inverser l'état de l'affichage standard (activé ou désactivé) pour l'exécution de la commande qui le suit (pas seulement pour la commande écho). Ce comportement se termine lorsque la commande est exécutée. Donc la commande @cd / d "C: Users Portable " ne sera affiché que si l'affichage standard est désactivé. La syntaxe du préfixe @ est la suivante (o est la commande à exécuter):

@<ordre>

La commande écho Verts l'affichage dans l'interprète, il peut:

  • changer le statut de l'affichage standard;
  • afficher l'état de l'affichage standard;
  • afficher un message ou une ligne vide dans l'interprète.

La désactivation de l'affichage standard peut s'effectuer via la syntaxe suivante (uniquement les erreurs et les messages de la commande écho sont affichés).

écho de

Activer l'affichage standard peut être effectué via la syntaxe suivante (tout est affiché).

écho nous

Utiliser sans paramètres, la commande écho renvoie le statut de la vue standard actuelle.

écho

Si nous répétons le script 1, la ligne @Écho off pour désactiver la vue standard sans que la commande soit affichée. Sur la deuxième ligne du script 1, la commande cls est utilisé pour vider la fenêtre de l’interprète de son contenu, cette commande ne prend aucun paramètre. Sa syntaxe est donc la suivante.

cls

La ligne suivante du script 1 est vide, elle ne sera donc pas prise en compte lors de l'exécution du script, ce qui le rendra plus lisible. La quatrième ligne est composée de la commande rem et une chaîne de caractères, cette commande vous permet d’insérer des remarques dans votre script. Si et seulement si l'affichage standard est activé, la commande rem sera affiché. La syntaxe de la commande rem est la suivante (o est la chaîne de caractères insérée dans la remarque).

La cinquième ligne du script 1, :: Ceci est un commentaire., est composé du préfixe :: et une chaîne de caractères. Le préfixe :: définit la chaîne de caractères qui la suit sous forme de commentaire; ce comportement se termine sur la première ligne de retour. Indépendamment de l’état de l’affichage standard, la chaîne de caractères précédée du préfixe :: ne sera pas affiché. La syntaxe est la suivante (o est le commentaire inséré).

Suit une autre ligne vide puis la commande echo Hello World !!!! Dj l? qui affiche Bonjour Monde !!!! Dj l? dans la fenêtre de l'interprète. La syntaxe suivante vous permet d’afficher un message même si l’affichage standard est désactivé (o est le message d’affichage).

écho <message>

Puis vient la commande écho. ce qui permet d'afficher la ligne vide que l'on voit dans l'affichage obtenu. Si un point suit directement la commande écho et qu'après le point il y a un retour de la ligne, celle-ci affiche une ligne vide.

écho.

Sur la ligne suivante se trouve la commande pause qui met en pause l'exécution du script jusqu'à ce que l'utilisateur appuie sur une touche du clavier, il affiche le message Appuyez sur une touche pour continuer … (quel que soit l'état actuel de la vue standard) et ne prend aucun paramètre. En script 1, cette commande permet de visualiser le contenu de la fenêtre de l'interpréteur avant la fermeture de celle-ci.

pause

I-D. Différence entre la commande rem et le préfixe :: ▲

Pour mieux comprendre la différence entre la commande rem et le préfixe ::, essayons le script 2.

1.
2
3
4
5
6
7.

cls


@écho de


pause
Aucune image disponible "width =" 370 "height =" 81

Comme vous le voyez dans la vue script 2, la commande Rem Note 1, est présente l'encoche; Lorsque l’écran standard est activé, toutes les commandes affichées sont affichées. La chaine :: Commentaire 1 n'est pas affiché, cela est dû au fait que le préfixe :: n'est pas une commande et n'est donc pas renvoyé par la vue standard. Puis vient la commande @Écho off qui désactive l’affichage standard sans afficher la commande, suivi de la commande Rem Note 2 qui ne s'affiche pas (l'affichage standard est jusqu'à présent désactivé), ni la chaîne :: commentaire 2 ce qui est en tout cas exclu par l'affichage standard.

C'EST À DIRE. Le personnage s'échappe

Les caractères spéciaux (également appelés caractères mta) sont des caractères qui ont une signification particulière pour l'interpréteur de commandes. Chaque fois que l'interprète les rencontre, il leur applique le traitement correspondant, indépendamment de leur position dans la ligne de commande. Voici la liste:

Et | ^ < > ()

Pour pouvoir les utiliser dans une chaîne de caractères, vous devez les échapper avec le caractère ^c'est-à-dire, mettez ce personnage devant lui. Ainsi, l'interprète saura qu'ils font partie d'une chaîne et qu'ils n'ont rien à voir avec la commande. Voir le script 3 à titre d'exemple.

1.
2
3

@écho de
écho ^Et ^| ^^ ^< ^> ^ (^)
pause

Il convient également de noter que d'autres caractères peuvent nécessiter une évasion, mais ils suivent d'autres règles. Le personnage % doit être caché par lui-même pour être considéré comme faisant partie d'une chaîne lorsqu'il est utilisé dans un script, comme indiqué dans le script 4.

1.
2
3

@écho de
écho %%
pause

Un autre cas est note, il concerne les personnages " et qui doit être échappé avec le personnage lorsqu'il est utilisé dans un paramètre cité. Dans le script 5, si les personnages " et n'avait pas été manqué, le résultat ne serait pas celui attendu. L'interprète aurait compris qu'il y avait une chaîne bloc-notes "cmd / c" et une chaine "% CD% ~% nx0" ", ce qui aurait entraîné une erreur dans l’évaluation de la commande.

1.
2
3

@écho de
courir comme / Utilisateur:% Nom d'utilisateur% "cmd / c  "bloc-notes "%CD%% ~ Nx0 ""
pause

Caractère d'échappement ^ peut également être utilisé pour écrire une même commande sur plusieurs lignes. Quand l'interprète rencontre le personnage ^ devant un retour à la ligne, il supprime ce caractère et renvoie la ligne, puis continue à lire les données fournies à la ligne suivante. Exemple avec le script 6.

1.
2
3
4

@écho de
écho foo ^
bar
pause
Aucune image disponible "width =" 333 "height =" 59

D'autres échappements existent, mais ils seront abordés plus tard dans ce document, car ils appliquent des ordres précis et ne concernent pas les autres. Par exemple, la commande écho qui considère le point comme une évasion de la chaîne qui le suit. Quand la commande écho est directement suivie d’un point; elle considère la chaîne située après le point comme un affichage de la chaîne et renvoie la ligne incluse. Cela vous permet d’utiliser un mot au début de la chaîne qui aurait autrement été considéré comme un paramètre. Exemple avec le script 7.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

@écho de

écho Afficher une ligne vide sans le point:
écho

écho.
écho.

écho Afficher une ligne vide avec le point:
écho.

écho.
écho.

écho Affichage de la chaîne "/?  Impression cette aide. "sans le point:
écho     /?  Impression cette aide.

écho.
écho.

écho Affichage de la chaîne "/?  Impression cette aide. "avec le point:
écho.    /?  Impression cette aide.

écho.
écho.
pause

Dans l'affichage ci-dessous, nous remarquons que l'affichage d'une ligne vide sans point renvoie l'état de l'affichage standard contrairement à celui avec un point. Si l'emplacement d'une ligne de retour avait été utilisé par plusieurs espaces, le résultat aurait été identique, quel que soit le nombre d'espaces. En effet, l'interprète n'évalue pas le nombre d'espaces entre deux composants d'une ligne de commande, il aurait donc considéré qu'aucun paramètre n'était fourni. C'est la même chose avec la chaîne /? Imprimer cette aide., l'interprète considère la sous-chaîne /? en tant que paramètre qui affiche l'aide dans la ligne de commande.

Escape_str_in_echo_cmd

Le tableau 2 résume les différents types d’échappement que nous venons de voir.

échappement

La description

^

Plac devant l'un des caractères spéciaux, soit & ^ | <> ()cela signifie que le caractère qui le suit fait partie de la chaîne et n'a rien à voir avec la commande.

Plac devant une ligne de retour, cela signifie que la ligne suivante fait partie de la même commande.

%

Plac devant le personnage % dans un script, cela signifie que le caractère qui le suit fait partie de la chaîne.

Plac devant l'un des personnages et " dans un paramètre cité, cela signifie que le caractère qui le suit fait partie de l'argument cité.

.

Plac immédiatement après la commande écho, cela signifie que la chaîne qui suit est une chaîne d'affichage et non un paramètre de la commande écho.

Tableau 2: Échappement

SI. Les bugs de la commande rem et du préfixe :: ▲

Un problème récurrent dans script de batch est-ce que des commentaires et des commentaires (fournis via rem et ::) causer des bugs dus à une mauvaise utilisation. La commande rem et le préfixe :: en prenant une chaîne de caractères comme paramètres, ils attendent une chaîne de caractères valide. Ainsi, les échappements doivent être utilisés pour les caractères suivants: & | ^ ()%.

Les variables sont gérées via la commande ensemble, il existe deux types dont voici la liste:

  • variables de chaîne de caractères;
  • nombre entier signe de variables.

Chaque type de variable est déclaré et marqué différemment; il est possible de les couler, c'est-à-dire de les passer d'un type à l'autre, à condition de respecter les règles suivantes:

  • une chaîne de caractères qui ne peut être numérique que si elle ne contient que des nombres;
  • un nombre peut toujours être transtyp en une chaîne de caractères (qui ne contiendra que des nombres).

Les variables sont accessibles via un identifiant qui leur est propre. Ainsi, chaque fois que cet identifiant est mentionné, l'interpréteur pourra fournir la valeur associée. Cela peut être fait en utilisant le personnage % des deux côtés de l'identifiant, on parle d'expansion de la variable. Par exemple avec la variable CHEMIN (qui est une variable d’environnement: fournie par le système), pour obtenir sa valeur; la syntaxe doit être utilisée % CHEMIN% comme dans le script 8.

1.
2
3

@écho de
écho % CHEMIN%
pause

Ce qui produirait un affichage similaire à celui ci-dessous.

CHEMIN

Les identificateurs de variable ne sont pas sensibles à la casse, c'est-à-dire que l'interpréteur ne fait pas la différence entre les majuscules et les minuscules lorsqu'il développe, crée ou modifie une variable. Donc les identifiants CHEMIN, Chemin et chemin identifier une seule et même variable.

II-A. Variables d'environnement ▲

Nous allons commencer par les variables d’environnement, elles sont toutes de type string. C'est le système d'exploitation qui définit leurs valeurs, soit parce que d'un système à l'autre, leurs valeurs peuvent être différentes, soit parce que ces variables sont définies de manière dynamique au fur et à mesure de leur développement. Cela permet d’accéder à des fichiers dont le chemin d’accès peut ne pas être identique d’une machine à l’autre ou d’obtenir, par exemple, l’heure ou la date dont les valeurs sont modifiées de façon permanente.

Dans le tableau 3, vous trouverez la liste de ces variables. Dans la première colonne, vous trouverez le nom de ces variables. ces noms sont réservés par le système et même s'il est possible de changer leur valeur lors de l'exécution du script, les modifications apportées prendront fin en même temps que le script. De plus, dans certains cas, la modification de leur valeur peut amener le script à mal évaluer l'environnement. La deuxième colonne donne la description de la valeur renvoyée par la variable. Et enfin, la troisième colonne donne la compatibilité en fonction de la version du système. Dans cette colonne, les systèmes NT sont mentionnés, il s'agit de la famille du système d'exploitation. Les systèmes NT sont des systèmes basés sur un noyau de type NT à partir du système Windows du même nom. Cette famille comprend le jour où ces lignes sont écrites:

  • Systèmes Windows NT X.Y (X étant la révision majeure et Y la révision mineure);
  • Systèmes Windows 2000
  • Systèmes Windows XP
  • Systèmes Windows Server 2003
  • Systèmes Windows Vista
  • Systèmes Windows Server 2008
  • Systèmes Windows 7
  • Systèmes Windows Server 2012
  • et les systèmes Windows 8.

Variable

La description

compatibilité

AllUsersProfile

Renvoie le chemin d'accès complet au répertoire des données utilisateur commun à tous les utilisateurs. Par défaut: HomeDrive %% ProgramData.

Disponible sur tous les systèmes NT.

Données d'application

Renvoie le répertoire de données d'application commun sous la forme
% UserProfile% AppData Roaming.

Disponible sur tous les systèmes NT.

CD

Renvoie le chemin complet du répertoire dans lequel le script est exécuté. Ce répertoire peut être différent du répertoire dans lequel le script a démarré (s'il a été déplacé au cours de son exécution).

Disponible sur tous les systèmes NT.

CMDCMDLINE

Renvoie la ligne de commande d'origine qui a appelé l'interpréteur de commandes.

Disponible sur tous les systèmes NT.

CMDEXTVERSION

Renvoie le numéro de version des extensions de commande du processeur de commandes en cours.

Disponible sur tous les systèmes NT.

CommonProgramFiles

Renvoie le chemin complet vers les applications 32 bits communes aux systèmes 32 bits ou les applications 64 bits vers 64 bits, telles que: % ProgramFiles% Fichiers communs.

Disponible sur tous les systèmes NT.

CommonProgramFiles (x86)

Renvoie le chemin complet du répertoire de fichiers communs 32bits sur les systèmes 64bits:
% ProgramFiles (x86)% Fichiers communs.

Disponible uniquement sur les systèmes NT 64bits.

Programme commun W6432

Renvoie le chemin complet du fichier commun des applications 16 bits sur les systèmes 64 bits et les systèmes Vista 32 bits et supérieurs: % ProgramW6432% Fichiers communs.

Disponible uniquement sur les systèmes NT 64 bits et les systèmes Vista 32 bits et supérieurs.

Nom de l'ordinateur

Renvoie le nom de l'ordinateur sur lequel le script est exécuté.

Disponible sur tous les systèmes NT.

ComSpec

Renvoie le chemin complet de l'interprète: % WinDir% system32 cmd.exe.

Disponible sur tous les systèmes NT.

Daté

Renvoie la date actuelle en utilisant le même format que la commande daté.

Disponible sur tous les systèmes NT.

ErrorLevel

Renvoie la valeur du code d'erreur actuel. Cette valeur est modifiée après chaque ligne de commande, en fonction du résultat de la commande. En général, la variable ErrorLevel renvoie 1 ou plus en cas d'erreur de la dernière commande et 0 si aucune erreur ne s'est produite. Cependant, il arrive que ce comportement varie en fonction des commandes, il est donc recommandé de se reporter à l'aide concernant cette commande.

Disponible sur tous les systèmes NT.

FP_NO_HOST_CHECK

CAROLINE DU NORD.

Disponible sur tous les systèmes NT.

Le plus haut numéro de numéro de noeud

Renvoie le numéro de nœud NUMA le plus élevé de l'ordinateur sur lequel le script est exécuté.

Disponible uniquement sur les systèmes NT 64bits.

HomeDrive

Renvoie le point de montage de la partition qui héberge les répertoires de l'utilisateur. Par défaut: C:.

Disponible sur tous les systèmes NT.

HomePath

Renvoie le chemin d'accès au répertoire de l'utilisateur actuellement connecté. Par défaut: Utilisateurs % nom d'utilisateur%.

Disponible sur tous les systèmes NT.

LocalAppData

Renvoie le répertoire local des données d'application sous la forme: % UserProfile% AppData Local.

Disponible sur tous les systèmes NT.

LogonServer

Renvoie l'URL locale du système d'exploitation sous la forme % Nom de l'ordinateur%.

Disponible sur tous les systèmes NT.

NUMBER_OF_PROCESSORS

Renvoie le nombre de cœurs logiques sur l'ordinateur sur lequel le script est exécuté.

Disponible sur tous les systèmes NT.

OS

Renvoie le type de noyau sur lequel est basé le système d'exploitation. Sur les systèmes NT, cette variable renvoie toujours la chaîne. Windows_NT.

Disponible sur tous les systèmes NT.

Chemin

Renvoie la liste des répertoires reconnus par le système comme contenant des exécutables. Chaque répertoire est répertorié par son chemin d'accès complet, suffixé d'un point-virgule. Si un exécutable se trouve dans l'un des répertoires de cette liste, il n'est pas nécessaire de fournir un chemin complet pour l'appeler sur la ligne de commande.

Disponible sur tous les systèmes NT.

PATHEXT

Retourne une liste des extensions de fichiers reconnues par le système comme étant à la fois des extensions de fichiers exécutables. Si une extension de fichier ne figure pas dans cette liste, le fichier ne peut pas être appelé en tant que commande.

Disponible sur tous les systèmes NT.

PROCESSOR_ARCHITECTURE

Renvoie le type d'architecture (32 / 64bits) du processeur sur lequel le script est exécuté. Les valeurs possibles sont: X86 pour les processeurs 32 bits, AMD64 pour les processeurs 64 bits basés sur l'architecture x86 et IA64 pour les processeurs Itanium.

Disponible sur tous les systèmes NT.

PROCESSOR_IDENTIFIER

Retourne une identification précise du processeur sur lequel le script est exécuté. Cette identification est une chaîne de caractères composée du type d'architecture suivi de la famille, du modèle, de la révision et enfin du fabricant du processeur.

Disponible sur tous les systèmes NT.

PROCESSOR_LEVEL

Retourne une identification précise de la famille de la micro-architecture du processeur.

Disponible sur tous les systèmes NT.

PROCESSOR_REVISION

Renvoie un modèle de processeur spécifique et l'identification de la révision sous la forme d'une chaîne de caractères représentant un nombre hexadécimal à deux octets, le premier pour le modèle et le second pour la révision.

Disponible sur tous les systèmes NT.

Données de programme

Renvoie le répertoire de données d'application 64 bits commun sous la forme: % SystemDrive% ProgramData.

Disponible uniquement sur les systèmes NT 64bits.

Fichiers de programme

Renvoie le chemin complet du répertoire ProgramFiles. Ce répertoire contient des applications 32 bits sur des systèmes 32 bits ou des applications 64 bits sur des systèmes 64 bits.

Disponible sur tous les systèmes NT.

ProgramFiles (x86)

Renvoie le chemin complet du répertoire ProgramFiles (x86). Ce répertoire contient des applications 32 bits sur des systèmes 64 bits.

Disponible uniquement sur les systèmes NT 64bits.

ProgramW6432

Renvoie le chemin complet du répertoire ProgramW6432. Ce répertoire contient les applications 16 bits sur les systèmes 64 bits et les systèmes Vista 32 bits et supérieurs.

Disponible sur les systèmes NT 32 et 64bits Vista et supérieurs.

Rapide

Renvoie la chaîne de configuration pour l'affichage standard, par défaut: $ P $ G. Voir l'aide de la commande rapide pour plus d'informations: invite /?.

Disponible sur tous les systèmes NT.

PSModulePath

Renvoie le chemin d'accès complet aux modules PowerShell.

Disponible uniquement sur Vista et les systèmes supérieurs. (XP avec mise à jour KB926140)

Publique

Renvoie le chemin complet du répertoire de documents publics sous la forme HomeDrive %% Users Public.

Disponible uniquement sur Vista et les systèmes supérieurs.

au hasard

Retourne un nombre aléatoire compris entre 0 et 32767.

Disponible sur tous les systèmes NT.

Nom de session

Retourne le nom de la session en cours. Par défaut: Console.

Disponible sur tous les systèmes NT.

SystemDrive

Renvoie le point de montage de la partition sur laquelle le système d'exploitation est installé.

Disponible sur tous les systèmes NT.

RacineSystème

Renvoie le chemin complet du système d'exploitation sous la forme
% SystemDrive% Windows.

Disponible sur tous les systèmes NT.

Temp

Renvoie le chemin d'accès complet au répertoire de fichiers temporaires de l'utilisateur. Par défaut: % UserProfile% AppData Local Temp.

Disponible sur tous les systèmes NT.

Temps

Renvoie l'heure actuelle en utilisant le même format que la commande temps.

Disponible sur tous les systèmes NT.

tmp

Même temp.

Disponible sur tous les systèmes NT.

UserDomain

Renvoie le nom de domaine de l'ordinateur sur lequel le script est exécuté. Si le système n'appartient pas à un domaine, le nom de domaine sera le nom de l'ordinateur sur lequel le script est exécuté.

Disponible sur tous les systèmes NT.

Nom d'utilisateur

Renvoie le nom de l'utilisateur actuellement connecté.

Disponible sur tous les systèmes NT.

Profil de l'utilisateur

Renvoie le chemin d'accès complet au répertoire d'utilisateurs de l'utilisateur actuellement connecté en tant que: HomeDrive %% Users % nom_utilisateur%.

Disponible sur tous les systèmes NT.

WinDir

Renvoie le chemin complet du répertoire d'installation du système. Par défaut: % SystemDrive% Windows.

Disponible sur tous les systèmes NT.

Tableau 3: Variables d'environnement

II-B. L'ensemble ▲

La commande ensemble variables gre dans l'interpréteur, cela permet:

  • créer une variable;
  • assigner une valeur à une variable
  • modifier le contenu d'une variable;
  • supprimer le contenu d'une variable;
  • effectuer des opérations mathématiques ou logiques entre les nombres;
  • Récupération de l'entrée d'un utilisateur pour la placer dans une variable
  • et jette le contenu d'une variable.

Voici la syntaxe de la commande ensemble.

Attribuez une valeur à la variable sous forme de chaîne de caractères (o est son identifiant et est une chaîne de caractères).

ensemble [« ]<variable>=<chane>[« ]

Attribuez à la variable une valeur sous forme de signe de nombre entier (o est une expression numérique à évaluer: détaillée plus loin).

ensemble /à [« ]<expression>[« ]

Attribuez à la variable une valeur, entrée par l'utilisateur, sous forme de chaîne de caractères après l'affichage de la chaîne d'invite, le cas échéant (o est son identifiant et o est une chaîne de caractères indique à l'utilisateur de l'inviter à entrer une chaîne de clés).

ensemble / p [« ]<variable>=[[[[<chane_invite>][« ]

Supprime la valeur de la variable de mémoire, son identifiant reste indexé par l'interpréteur, mais sa valeur est indéfinie.

ensemble [« ]<variable>=[« ]

Voici les règles habituelles de la commande ensemble:

  • Si la commande ensemble est utilisé sans paramètre, il affiche les variables définies dans le contexte actuel (détaillé plus tard).
  • S'il est utilisé avec comme paramètre une chaîne (ou un nom de variable), sans valeur ni signe gal; il affiche ensuite la variable dont le nom correspond à la chaîne de paramètres donnée et / ou les variables dont le nom commence par la chaîne de paramètres donnée.
  • Si elle est utilisée avec un nom de variable et un signe gal non valide, alors le contenu de la variable est vide de mémoire, il est possible de vérifier si une variable est définie, mais nous aborderons ce point dans le chapitre suivant.
  • Toute chaîne non numérique dans l'expression de valeur est traitée comme un identificateur de variable et est convertie en un nombre avant d'être utilisée (utilisée avec le paramètre ), si la variable n’existe pas ou est indéfinie, elle prend la valeur 0.
  • Une valeur d'expression numérique doit toujours être placée entre guillemets pour permettre l'utilisation d'opérateurs logiques et d'opérateurs de regroupement.

Regardons de plus près le fonctionnement de la commande ensemble avec le script 9.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20

@écho de
ensemble VAR_Espace_Un="Ma chaine avec des espaces"
ensemble VAR_Espace_Deux "=Mon canal avec des espaces "
ensemble "VAR_Espace_Trois=Mon canal avec des espaces "

ensemble / p VAR_Saisie_Un=    ma première saisie:    
ensemble / p "VAR_Saisie_Two=    ma saisie deux: "
ensemble / a VAR_Calcul_Un=1 + 10
ensemble / a VAR_Calcul_Two "=2 + 20 "
ensemble / a "VAR_Calcul_Trois=3 + 30 "
écho.
écho %% VAR_Espace_Un
écho %% VAR_Espace_Deux
écho %% VAR_Espace_Trois
écho.
ensemble VAR_Saisie
écho.
ensemble VAR_Calcul
écho.
pause
Variable_Quote

Comme vous pouvez le constater, les guillemets occupent une place de choix dans ce script. observez où ils sont placés. De la ligne 2 à la ligne 4, les valeurs des variables sont des chaînes de caractères avec des espaces. La déclaration de la variable VAR_Espace_Un se fait avec des guillemets placés des deux côtés de la chaîne, la déclaration de la variable VAR_Espace_Deux se fait avec des guillemets: une place devant le signe gal et l’autre au bout de la chaîne; la déclaration de la troisième variable VAR_Espace_Trois se fait avec des guillemets: un avant le nom de la variable et l’autre en fin de ligne. Si nous nous référons à l'affichage obtenu, nous remarquons que les première et troisième variables affichent une sortie correcte; la seconde variable quand ça ne marche pas; il est donc facile de déduire que si les guillemets s'ouvrent avant l'identifiant de la variable et se ferment après la valeur de la variable, ils ne font pas partie de la variable; et si les guillemets s’ouvrent avant la valeur de la variable et se ferment après la valeur de la variable, ils font partie de la variable.

Les deux saisies de l'utilisateur ont également abouti à un résultat intéressant, la ligne de commande qui décline VAR_Saisie_Un n'utilisez pas de guillemets; par contre the line of order VAR_Saisie_Deux, elle, en utilise. Lors de l'affichage des invitations de saisie utilisateur, les espaces se sont mutés avant les chaînes d'invités ont disparu, et ceux-ci se sont après affichés. Sur les espaces en début de ligne sont ignorés et ceux de la fin sont considérés comme faisant partie de la chaîne d'invitation.

En ce qui concerne les variables VAR_Calcul_XXX, elles sont toutes préférables mais respectent également les règles de syntaxe; c’est – dire toujours mettre l’expression numérique entre guillemets. Cela sera utile dans la suite du chapitre.

II-C. Les variables de type chane de caractères ▲

Ce sont, mon sens, les plus utilise en batch. Ce sont toutes les variables composées de caractères alphanumériques et autres caractères. Les chansons de caractères sont claires via la commande ensemble et il n'est pas nécessaire d'utiliser des guillemets pour que les espaces soient pris en compte, en tant que partie intégrante de la chaîne, et ce, ce sont eux qui sont placés dans la chaîne.

Elles offrent aussi d'autres possibilités comme la substitution de chaîne dans l'expansion de la variable. Ainsi avec la syntaxe suivante, il est possible de modifier la variable lors de son expansion sans que cela ne soit que sa valeur (o est l'identifiant de la variable, is the chane remplacer et est la chane inser la place de ). Exemple avec le script 10.

%:=%

1.
2
3
4
5
6

@écho de
ensemble "X=une chane "
écho La variable avec substitution: % X: une = ma%
écho La valeur réelle de la variable: %X%
écho.
pause
Variable_Parse_String_0

peut aussi tre une chane prcde d'un astrisque (*), dans ce cas, la substitution commence par la valeur de la variable et se termine après la première occurrence de la chaîne spéciale dans la substitution. Exemple avec le script 11.

1.
2
3
4
5

@écho de
ensemble "X=chaîne"
écho Substitution avec astrisque: % X: * t = d%
écho.
pause
Variable_Parse_String_1

Il ne faut jamais utiliser un astrisque seul dans la substitution, sans quoi, l'interprète de commande se ferme sans autre forme de procs. L 'astrisque en fin de chaîne ne provoque pas d' erreur, mais ne permet pas la substitution, la variable est étendue avec sa valeur d 'origine.

La substitution ne modifie pas la valeur de la variable, elle transforme juste la variable au moment de l'expansion. Pour modifier la valeur de la variable, il faut faire avec la commande ensemble. Exemple avec le script 12.

1.
2
3
4
5
6

@écho de
ensemble "VAR=ma chane "
écho % VAR%
ensemble "VAR=% VAR: chane = voiture%"
écho % VAR%
pause
Variable_Parse_String_2.2

Vous pouvez aussi ne pas développer une partie d'une chanson en slectionnant les caractères voulus. Cela se fait via la syntaxe suivante (o est l&#39;identifiant de la variable, est l&#39;index du premier caractre en partant de 0 et est la longueur de la slection). Exemple avec le script 13.

%:~,%

1.
2
3
4
5
6

@écho de
ensemble "VAR=ma chane"
écho %VAR:~0,2%
ensemble "VAR=%VAR:~3,6%"
écho %VAR%
pause
Image non disponible" width="363" height="74

Si la n&#39;est pas spcifie, tout le reste de la chane est slectionn, en partant du caractre fourni en . Si une des valeurs donnes est ngative, alors la valeur utilise est la longueur totale de la chane ajoute la valeur ngative.

1.
2
3
4
5
6
7.
8
9
dix.
11

@écho de

ensemble "VAR=ma chane"

écho %VAR:~-6%


écho %VAR:~0,-7%


pause
Variable_Parse_String_2

II-D. Les variables de type nombre entier sign▲

The command set /a permet d&#39;utiliser les nombres entiers signs allant de -2147483648 +2147483647 (cods sur 32bits). Si vous n&#39;utilisez pas le paramtre /a dans la commande, alors la squence de chiffres sera considre comme tant une chane de caractres, et non un nombre. La syntaxe de la commande set /a est la suivante.

ensemble /a <expression>

utilise, quant elle, la syntaxe suivante.

[« ]<s'identifier>[[[[<affectation>[{[{[{[<sous-expression>]][« ]

Les expressions numriques doivent tre places entre des guillemets si elles contiennent des oprateurs logiques ou de groupement (dtaill plus loin dans ce chapitre). Ces diffrentes constituantes sont:

  • qui est l&#39;identifiant de la variable de destination;
  • qui est l&#39;oprateur d&#39;attribution de l&#39;expression, comme le signe gal qui effectue l&#39;opration d&#39;attribuer une valeur une variable, d&#39;autres oprateurs d&#39;attribution seront dtaills dans cette section;
  • puis soit qui est une valeur immdiate (un nombre quelconque), soit qui est une sous-expression, ces dernires seront dtailles dans le reste de cette section.

Vous pouvez spcifier plusieurs expressions en les sparant par des virgules.

@écho de
ensemble /a "VAR1=1", "VAR2=2"
écho VAR1: %VAR1%
écho VAR2: %VAR2%
pause
Image non disponible" width="354" height="82

Les chanes de caractres prsentes dans l&#39;expression sont considres comme des variables et sont expanses ( l&#39;exception de l&#39;identifiant de la variable de destination), cela permet de faire des oprations sur des variables sans avoir utiliser de symbole % pour leur expansion.

@écho de
ensemble /a "VAR1=1"
ensemble /a "VAR2=VAR1"
écho VAR1: %VAR1%
écho VAR2: %VAR2%
pause
Set_a_var_unexpand

Si un nom de variable inexistante ou indfinie est utilis, alors elle prend la valeur 0.

1.
2
3
4
5

@écho de

ensemble /a "VAR2=VAR1"
écho VAR2: %VAR2%
pause
Image non disponible" width="358" height="60

Les sous-expressions sont constitues de nombres, d&#39;oprateurs et ventuellement de parenthses, ces dernires s&#39;utilisent de la mme manire qu&#39;en mathmatiques et elles n&#39;ont pas besoin d&#39;tre chappes si, et seulement si, les guillemets sont utiliss. Toutes les constituantes d&#39;une sous-expression sont soumises la prsance, c&#39;est–dire l&#39;ordre dans lequel les diverses constituantes vont tre values. L&#39;ordre de prsance utilis est le suivant (dans l&#39;ordre dcroissant d&#39;valuation):

  • le groupement soit ( );
  • les oprateurs unaires ! ~ –;
  • les oprateurs arithmtiques * / %;
  • les oprateurs arithmtiques + –;
  • le dcalage logique <>;
  • le ET au niveau du bit Et;
  • le OU exclusif au niveau du bit ^;
  • le OU inclusif au niveau du bit |;
  • l&#39;&#39;attribution = *= /= %= += -= &= ^= |= <>=;
  • le sparateur d&#39;expression ,.

Il faut galement noter que l&#39;utilisation du nombre -2147483648 tel quel dans une expression provoque une erreur, c&#39;est d au transtypage effectu par l&#39;interprteur. Ce dernier value d&#39;abord la chane 2147483648 afin de la transtyper puis lui applique l&#39;oprateur unaire . Mais comme le nombre 2147483648 va au-del de la dfinition d&#39;un nombre sur 32bits, l&#39;opration gnre une erreur, exemple avec le script suivant.

1.
2
3
4
5
6
7.
8
9
dix.

@écho de
écho Nombre brute:
ensemble /a "ParseError=-2147483648"
écho %ParseError%
echo.
écho Nombre avec valuation:
ensemble /a "ParseError=-2147483647 - 1"
écho %ParseError%
echo.
pause
Parse_Error

Une autre mthode qui fonctionne pour ce cas est la suivante.

1.
2
3
4
5

@écho de
ensemble "SInt32=-2147483648"
ensemble /a "SInt32"
écho %SInt32%
pause
TransTypage

II-D-1. Les oprations arithmtiques▲

The command set /a prend en charge les cinq oprations arithmtiques suivantes:

  • l&#39;addition;
  • la soustraction;
  • la multiplication;
  • la division;
  • et le modulo (le modulo est une opration qui sert rcuprer le reste d&#39;une division).

Oprateur arithmtique

Oprateur d&#39;attribution

Opration effectue

+

+=

Une addition

-=

Soustraction

*

*=

Multiplication

/

/=

Division

%

%=

Modulo

Tableau 4: Oprations arithmtiques

Une note particulire pour le modulo: dans un script de commande, le symbole du modulo % doit tre prfix du caractre d&#39;chappement %. Dans ce cas, c&#39;est un pige dans lequel le novice peut se perdre, le premier symbole % est un caractre d&#39;chappement qui permet au deuxime symbole %, le modulo, d&#39;tre pris en compte l&#39;excution du script. Dans l&#39;interprteur de commande, le modulo (%) n&#39;as pas besoin d&#39;tre chapp, c&#39;est une spcificit du script. Ainsi la commande suivante fonctionne dans l&#39;interprteur.

ensemble /a "Mod=5 % 2"

Alors que celle-ci ne fonctionne pas.

ensemble /a "Mod=5 %% 2"

Modulo_0

Dans un script, par contre, c&#39;est l&#39;inverse.

1.
2
3
4
5
6

@écho de
ensemble /a "Mod=5 % 2"
écho Mod1: %Mod%
ensemble /a "Mod=5 %% 2"
écho Mod2: %Mod%
pause
Modulo_1

Ainsi, les oprations arithmtiques s&#39;utilisent de manire classique dans les sous-expressions. Si une variable inexistante ou indfinie est utilise dans une sous-expression, elle prend la valeur 0, exemple avec le script 21.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13

@écho de
ensemble /a "Un=1"
ensemble /a "Deux=1 + 1"
ensemble /a "Trois=4 - 1"
ensemble /a "Quatre=2 * 2"
ensemble /a "Cinq=10 / 2"
ensemble /a "Six=26 %% 10"
ensemble /a "Sept=(( 2 + 1 ) * 2 ) + 1"

ensemble /a "Huit=8+Dix","Neuf=10-Un"
écho %Un%, %Deux%, %Trois%, %Quatre%, %Cinq%, %Six%, %Sept%, %Huit%, %Neuf%
echo.
pause
Image non disponible" width="388" height="63

L&#39;attribution permet d&#39;effectuer des oprations sur des variables existantes, si une variable inexistante ou indfinie est utilise, elle prend la valeur 0.

1.
2
3
4
5
6
7.
8
9
dix.
11
12

@écho de
ensemble /a "Attrib1=1","Attrib2=2","Attrib3=3","Attrib4=4","Attrib5=5"

ensemble /a "Attrib0+=1"
ensemble /a "Attrib1+=1"
ensemble /a "Attrib2*=2"
ensemble /a "Attrib3-=2"
ensemble /a "Attrib4/=2"
ensemble /a "Attrib5%%=2"
écho %Attrib0%, %Attrib1%, %Attrib2%, %Attrib3%, %Attrib4%, %Attrib5%
echo.
pause
Variable_Attribution

II-D-2. Les oprations logiques▲

Elles ne peuvent s&#39;effectuer que sur des nombres et suivent les rgles de l&#39;algbre de Boole. Les oprations logiques prises en charge par la commande set /a possdent, elles aussi, des oprateurs d&#39;attribution. Exemple avec le script 23.

Oprateur logique

Oprateur d&#39;attribution

La description

Et

&=

ET logique au niveau du bit. (Bitwise AND)

^

^=

OU exclusif au niveau du bit. (Bitwise XOR)

|

|=

OU inclusif au niveau du bit. (Bitwise OR)

<<

<<=

Dcalage logique vers la gauche. Le bit entrant est zro (pour l&#39;lvation par puissances de deux).

>>

>>=

Dcalage logique vers la droite. Le bit entrant est gal au bit de signe (pour la propagation du bit de signe).

Tableau 5: Les oprateurs logiques

@écho de
ensemble /a "Val1=-2147483647 - 1"
ensemble /a "Val2=1"
ensemble /a "Val1SwitchL01=Val1<<1","Val1SwitchL15=Val1<<15","Val1SwitchL31=Val1<<31"
ensemble /a "Val2SwitchL01=Val2<<1","Val2SwitchL15=Val2<<15","Val2SwitchL31=Val2<<31"
ensemble /a "Val1SwitchR01=Val1>>1","Val1SwitchR15=Val1>>15","Val1SwitchR31=Val1>>31"
ensemble /a "Val2SwitchR01=Val2>>1","Val2SwitchR15=Val2>>15","Val2SwitchR31=Val2>>31"
ensemble /a "Val1AttribSwitchR=Val1","Val1AttribSwitchR>>=15"
ensemble /a "Val2AttribSwitchL=Val2","Val2AttribSwitchL<<=15"
écho %Val1% ^<^< 1: %Val1SwitchL01%
écho %Val1% ^<^< 15: %Val1SwitchL15%
écho %Val1% ^<^< 31: %Val1SwitchL31%
echo.
écho %Val2% ^<^< 1: %Val2SwitchL01%
écho %Val2% ^<^< 15: %Val2SwitchL15%
écho %Val2% ^<^< 31: %Val2SwitchL31%
echo.
écho %Val1% ^>^> 1: %Val1SwitchR01%
écho %Val1% ^>^> 15: %Val1SwitchR15%
écho %Val1% ^>^> 31: %Val1SwitchR31%
echo.
écho %Val2% ^>^> 1: %Val2SwitchR01%
écho %Val2% ^>^> 15: %Val2SwitchR15%
écho %Val2% ^>^> 31: %Val2SwitchR31%
echo.
écho %Val1% ^>^>= 15: %Val1AttribSwitchR%
écho %Val2% ^<^<= 15: %Val2AttribSwitchL%
echo.
ensemble /a "Val3=1431655765"
ensemble /a "Val4=-858993460"
ensemble /a "Val3LogicalOrVal4=Val3 | Val4"
ensemble /a "Val3LogicalXorVal4=Val3 ^ Val4"
ensemble /a "Val3LogicalAndVal4=Val3 Et Val4"
ensemble /a "Val3AttribOrVal4=Val3","Val3AttribOrVal4|=Val4"
ensemble /a "Val3AttribXorVal4=Val3","Val3AttribXorVal4^=Val4"
ensemble /a "Val3AttribAndVal4=Val3","Val3AttribAndVal4Et=Val4"
écho %Val3% ^| %Val4%: %Val3LogicalOrVal4%
écho %Val3% ^|= %Val4%: %Val3AttribOrVal4%
echo.
écho %Val3% ^^ %Val4%: %Val3LogicalXorVal4%
écho %Val3% ^^= %Val4%: %Val3AttribXorVal4%
echo.
écho %Val3% ^Et %Val4%: %Val3LogicalAndVal4%
écho %Val3% ^Et= %Val4%: %Val3AttribAndVal4%
echo.
pause
Variable_AlgBool

II-D-3. Les oprateurs unaires▲

N.B.: Dans les sections II.D.3, II.ELes nombres entiers signs en notation hexadcimale et II.FLes nombres entiers signs en notation octale de ce document, sont abords diffrents concepts de reprsentation numrique communment utiliss en informatique, tels que:

  • l&#39;criture de nombre en binaire;
  • l&#39;criture de nombre en hexadcimal;
  • l&#39;criture de nombre en octal;
  • la reprsentation des nombres en complment un;
  • la reprsentation des nombres entiers signs en complment deux.

Il est donc ncessaire, si vous ne les connaissez pas, de faire des recherches sur Wikipdia.

Les oprateurs unaires ne s&#39;appliquent qu&#39;aux nombres qu&#39;ils prcdent, ils ne possdent donc pas d&#39;oprateur d&#39;attribution. Leur syntaxe est la suivante (o est l&#39;oprateur unaire et est le nombre auquel il s&#39;applique).

<unaire><nombre>

Oprateur unaire

La description

!

NON logique, renvoie 1 si le nombre est gal 0 et 0 sinon. (Logical NOT).

~

NON au niveau du bit, complment un. (Bitwise NOT)

Renvoie la valeur inverse, soit un nombre ngatif si le nombre d&#39;origine est positif, complment deux. (NEG)

Tableau 6: Les oprateurs unaires

Exemple avec le script 24.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31.
32
33
34

@écho de



ensemble /a "Val1=2147483647"
ensemble /a "Val2=1"
ensemble /a "Val3=0"

ensemble /a "LogicalNOT_Val1=!Val1"
ensemble /a "LogicalNOT_Val2=!Val2"
ensemble /a "LogicalNOT_Val3=!Val3"

ensemble /a "BitwiseNOT_Val1=~Val1"
ensemble /a "BitwiseNOT_Val2=~Val2"
ensemble /a "BitwiseNOT_Val3=~Val3"

ensemble /a "NEG_Val1=-Val1"
ensemble /a "NEG_Val2=-Val2"
ensemble /a "NEG_Val3=-Val3"

écho              ╔════════════════════════════════════════╗
écho              ║                 Nombre                 ║
écho ╔════════════╬═════════════╦═════════════╦════════════╣
écho ║ Oprateur  ║ %Val1%%Val2%%Val3%écho ╠════════════╬═════════════╬═════════════╬════════════╣
écho ║ LogicalNOT ║ %LogicalNOT_Val1%%LogicalNOT_Val2%%LogicalNOT_Val3%écho ╠════════════╬═════════════╬═════════════╬════════════╣
écho ║ BitwiseNOT ║ %BitwiseNOT_Val1%%BitwiseNOT_Val2%%BitwiseNOT_Val3%écho ╠════════════╬═════════════╬═════════════╬════════════╣
écho ║ NEG        ║ %NEG_Val1%%NEG_Val2%%NEG_Val3%écho ╚════════════╩═════════════╩═════════════╩════════════╝

echo.
pause
Unaire

II-E. Les nombres entiers signs en notation hexadcimale▲

Les nombres en notation hexadcimale doivent tre dclars comme des nombres entiers en notation dcimale (ce que nous avons utilis jusqu&#39; maintenant) avec la commande set /a "" et toujours tre prfixs par 0x (chiffre zro suivi de la lettre x). The command set /a a pour effet de transformer toutes les valeurs entres en valeurs numriques. Si c&#39;est une chane de caractres alors la commande cherchera une variable portant ce nom, si c&#39;est un nombre hexadcimal alors la commande set /a codera le nombre tel quel en binaire. Cependant, mme si un nombre est fourni en notation hexadcimale, l&#39;interprteur l&#39;expanse toujours en notation dcimale, exemple avec le script 25.

1.
2
3
4
5

@écho de

ensemble /a "Hexa=0x1 + 0x3"
écho Rsultat:    %Hexa%
pause
Hexa_0

Le rsultat du script 25 nous montre que le calcul s&#39;effectue correctement, de mme avec le script 26.

1.
2
3
4
5
6

@écho de

ensemble /a "Hexa=0x5 + 0x8"

écho Rsultat:    %Hexa%
pause
Hexa_1

Jusque-l tout va bien mme si le rsultat n&#39;est pas en notation hexadcimale, il est quand mme celui attendu. Le problme c&#39;est que l&#39;interprteur de commande utilise toujours la reprsentation en complment deux pour coder un nombre entier sign. Ainsi, ds lors que l&#39;on utilise un nombre en notation hexadcimale suprieur 0x7FFFFFFF (soit 2147483647 en notation dcimale), ce nombre est en fait un nombre ngatif comme le montre le script 27.

1.
2
3
4

@écho de
ensemble /a "Hexa=0x80000000"
écho Rsultat:    %Hexa%
pause
Hexa_2

Un rsultat plutt droutant pour quiconque ne s&#39;y attend pas, en effet la reprsentation en complment deux code les nombres ngatifs de 0xFFFFFFFF, soit -1, 0x80000000, soit -2147483648. Exemple avec le script 28.

1.
2
3
4
5
6

@écho de

ensemble /a "Hexa=0x80000000 + 0x7FFFFFFF"

écho Rsultat:    %Hexa%
pause
Variable_In_tSign_Hex

Comme vous pouvez le voir, on additionne 0x80000000 (soit -2147483648 en reprsentation hexadcimale en complment deux) 0x7FFFFFFF (soit +2147483647, toujours dans la mme reprsentation) ce qui nous donne le rsultat de -1, le rsultat est un nombre entier sign dcimal utilisant la reprsentation en complment deux cod sur 32bits soit 0xFFFFFFFF. Pour rcuprer un nombre hexadcimal, il faut le calculer l&#39;aide d&#39;un algorithme de divisions successives; et pour les nombres ngatifs, de l&#39;oprateur unaire Bitwise NOT dont dispose la commande set /a, voir le script 29.

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46

@écho de

ensemble "SInt32=-2147483648"

ensemble /a "SInt32"

ensemble /a "SInt32=~SInt32"


ensemble /a "Nibble0= SInt32 %% 16","HighOrder0= SInt32 / 16"
ensemble /a "Nibble1=HighOrder0 %% 16","HighOrder1=HighOrder0 / 16"
ensemble /a "Nibble2=HighOrder1 %% 16","HighOrder2=HighOrder1 / 16"
ensemble /a "Nibble3=HighOrder2 %% 16","HighOrder3=HighOrder2 / 16"
ensemble /a "Nibble4=HighOrder3 %% 16","HighOrder4=HighOrder3 / 16"
ensemble /a "Nibble5=HighOrder4 %% 16","HighOrder5=HighOrder4 / 16"
ensemble /a "Nibble6=HighOrder5 %% 16"
ensemble /a "Nibble7=HighOrder5 / 16"

ensemble /a "Nibble0=15 - Nibble0"
ensemble /a "Nibble1=15 - Nibble1"
ensemble /a "Nibble2=15 - Nibble2"
ensemble /a "Nibble3=15 - Nibble3"
ensemble /a "Nibble4=15 - Nibble4"
ensemble /a "Nibble5=15 - Nibble5"
ensemble /a "Nibble6=15 - Nibble6"
ensemble /a "Nibble7=15 - Nibble7"

ensemble "LSW=%Nibble3% %Nibble2% %Nibble1% %Nibble0%"

ensemble "MSW=%Nibble7% %Nibble6% %Nibble5% %Nibble4%"
écho %MSW% %LSW%

ensemble "SInt32=2147483647"
ensemble /a "SInt32"
ensemble /a "Nibble0= SInt32 %% 16","HighOrder0= SInt32 / 16"
ensemble /a "Nibble1=HighOrder0 %% 16","HighOrder1=HighOrder0 / 16"
ensemble /a "Nibble2=HighOrder1 %% 16","HighOrder2=HighOrder1 / 16"
ensemble /a "Nibble3=HighOrder2 %% 16","HighOrder3=HighOrder2 / 16"
ensemble /a "Nibble4=HighOrder3 %% 16","HighOrder4=HighOrder3 / 16"
ensemble /a "Nibble5=HighOrder4 %% 16","HighOrder5=HighOrder4 / 16"
ensemble /a "Nibble6=HighOrder5 %% 16"
ensemble /a "Nibble7=HighOrder5 / 16"
ensemble "LSW=%Nibble3% %Nibble2% %Nibble1% %Nibble0%"
ensemble "MSW=%Nibble7% %Nibble6% %Nibble5% %Nibble4%"
écho %MSW% %LSW%
pause
Variable_Int_Sign_2_HexDecForm

La sortie du script 29 nous donne bien des nombres hexadcimaux, mais dans une reprsentation dcimale (80000000 soit -2147483648 cod 0x80000000 et 715151515151515 soit 2147483647 cod 0x7FFFFFFF), pour pouvoir les convertir dans une notation hexadcimale; il nous faut utiliser les conditions que nous tudierons au prochain chapitre.

II-F. Les nombres entiers signs en notation octale▲

Les nombres en notation octale fonctionnent comme les autres et supportent les mmes oprations. Pour tre considrs par l&#39;interprteur comme des nombres en notation octale, ils doivent tre prfixs par 0 (chiffre zro). Ils vont donc de -2147483648 2147483647 (cods sur 32bits) soit en notation octale -020000000000 +017777777777. Les nombres en notation octale sont cods tels quels en binaire, mais le principe selon lequel tout nombre est expans en entier sign en notation dcimale cod en complment deux s&#39;applique aussi pour eux. Notez aussi qu&#39;ils ont le mme problme de transtypage que les nombres dcimaux, exemple avec le script 30.

@écho de
ensemble /a "Octal1=-017777777777 - 1"
ensemble /a "Octal2=017777777777"
ensemble /a "Octal3=Octal1 + Octal2"
écho Octal1: %Octal1%
écho Octal2: %Octal2%
écho Octal3: %Octal3%
pause
Octal_0

Notez aussi que l&#39;utilisation des nombres 08 et 09 gnre toujours une erreur du fait qu&#39;ils sont prfixs par 0; et, que 8 et 9 ne sont pas des chiffres octaux. Lorsque la commande set /a rencontre un 0 en dbut de nombre, elle considre que tous les chiffres qui se trouvent aprs sont des octaux et lorsqu&#39;elle rencontre 8 ou 9, le transtypage ne peut s&#39;effectuer et la commande se termine sur une erreur. Exemple avec le script 31.

@écho de
écho Nombre 08:
ensemble /a "Octal1=08"
echo.
écho Nombre 09:
ensemble /a "Octal1=09"
echo.
pause
Octal_1

Les conditions sont supportes par la commande si. Elle permet d&#39;effectuer des comparaisons de toutes sortes et d&#39;excuter des commandes en fonction du rsultat de cette comparaison. autre et sinon si sont, quant eux, des paramtres de la commande si et ne peuvent tre utiliss qu&#39; l&#39;intrieur de la commande si.

III-A. If, else, else if, not et /i▲

The command si se traduit simplement par si: si la condition est vraie, fais ceci; elle peut tre accompagne par le paramtre autre qui se traduit par sinon: si la condition est vraie, fais ceci, sinon fais cela. La syntaxe de la commande si est la suivante.

si <chattedition> <commande1> [[[[autre <commande2>]

Comme vous pouvez le voir sur la syntaxe de la commande si, si vient en premier suivi de sa et d&#39;une commande (), puis vient autre et une commande (), on peut le traduire par:

  • si (si) la se vrifie alors la s&#39;excute;
  • sinon (autre) c&#39;est la qui s&#39;excute.

Le paramtre autre ne peut tre utilis seul, il doit toujours tre utilis avec la commande si, et tre sur la mme ligne. Il y a deux rgles importantes garder en tte lorsqu&#39;on utilise des conditions:

  • la premire est que l&#39;on ne peut utiliser qu&#39;un maximum de 2048 caractres (sous Windows XP et infrieur) ou un peu plus de 4096 caractres (sous Windows Vista et suprieur) par ligne de commande, limite trs vite atteinte avec plusieurs conditions, plus leurs commandes et leurs paramtres;
  • et la deuxime est que les parenthses sont prises en compte par l&#39;interprteur de commande comme des oprateurs de bloc, c&#39;est pour cela qu&#39;il faut les chapper lorsque l&#39;on ne s&#39;en sert pas cette fin.

Les oprateurs de bloc permettent d&#39;utiliser un bloc de commande en lieu et place d&#39;une commande. Ainsi, chaque fois que la syntaxe autorise l&#39;utilisation d&#39;une commande, celle-ci peut tre remplace par un bloc de commandes.

Ainsi la syntaxe de la commande si peut tre modifie de la manire suivante.

Syntaxe des conditions if et else avec parenthses

Sélectionnez

si <chattedition> (
    <commande1>
    <commande2>
) autre (
    <commande3>
    <commande4>
)

L&#39;utilisation des parenthses comme oprateurs de bloc permet d&#39;excuter plusieurs commandes, par condition vrifie, au lieu d&#39;une seule. La parenthse ouvrante associe une condition doit se trouver sur la mme ligne que cette dernire; si une autre condition est utilise conjointement, alors elle doit se trouver sur la mme ligne que la parenthse fermante associe la condition qui la prcde.

The command si autorise aussi le paramtre sinon si qui se traduit par sinon si, ce dernier permet de poser une condition supplmentaire avant l&#39;excution ventuelle du autre. La syntaxe serait la suivante.

si <chattedition1> <cmd1> [[[[autre si <chattedition2> <cmd2>][[[[autre <cmd3>]

Les oprateurs de bloc fonctionnent de la mme manire avec le paramtre sinon si en plus. Il faut aussi noter que le paramtre sinon si peut tre utilis autant de fois que l&#39;on veut dans la commande si.

Syntaxe des conditions if, else if et else

Sélectionnez

si <chattedition1> (
    <commande1>
    <commande2>
) autre si <chattedition2> (
    <commande3>
    <commande4>
) autre si <chattedition3> (
    <commande5>
    <commande6>
) autre (
    <commande7>
    <commande8>
)

La syntaxe ci-dessus pourrait tre traduite par:

  • si (si) la est vraie: excuter et ;
  • sinon si (sinon si) est vraie: excuter et ;
  • sinon si (sinon si) est vraie: excuter et ;
  • sinon (autre): excuter et .

Les conditions associes la commande si et au paramtre sinon si prennent le modificateur ne pas qui permet d&#39;excuter une commande si la condition est fausse. Le modificateur ne pas ne s&#39;applique pas toutes les conditions de la mme structure de contrle. Si le paramtre sinon si est utilis conjointement, son comportement dpendra de la prsence, ou non, du modificateur ne pas l&#39;intrieur de la condition.

si ne pas <chattedition1> <cmd1> autre si <chattedition2> <cmd2> autre <cmd3>

La commande ci-dessus se traduit par:

  • si (si) la est fausse: excuter la ;
  • sinon (sinon si), si la est vraie: excuter la ;
  • sinon (autre), si la est vraie et que la est fausse, excuter la .

Les conditions associes la commande si et au paramtre sinon si prennent le modificateur /i qui permet de ne pas tenir compte de la casse lorsque la condition traite des chanes de caractres. Ce modificateur ne fonctionne que sur les conditions qui traitent des chanes de caractres. Si le paramtre sinon si est utilis conjointement, son comportement dpendra de la prsence, ou non, du modificateur /i l&#39;intrieur de la condition.

si /i <chattedition1> <cmd1> autre si /i <chattedition2> <cmd2> autre <cmd3>

Se traduit par:

  • si (si) la est vraie, sans tenir compte de la casse, excuter la ;
  • sinon si (sinon si) la est vraie, sans tenir compte de la casse, excuter la ;
  • sinon (autre), si la est fausse sans tenir compte de la casse et que la est fausse sans tenir compte de la casse, excuter la .

Nous allons maintenant voir quelles sont les conditions supportes par la commande si et le paramtre sinon si.

III-B. La condition exist

La condition exister permet de tester si un chemin d&#39;accs ou un fichier existe. Elle peut tre utilise avec le paramtre sinon si et le modificateur ne pas. Le modificateur /i ne fonctionne pas sur cette condition. Sa syntaxe est la suivante, o est le chemin d&#39;accs ou le fichier tester. Si le chemin d&#39;accs contient des espaces, il doit tre plac entre guillemets.

si [[[[ne pas] exister [« ]<chemin>[« ] <ordre>

Exemple avec le script 32.

1.
2
3

@écho de
si exister "%cd%" écho %cd% existe bien.
pause
If_Exist

III-C. La condition defined

La condition défini permet de tester si une variable a une valeur dfinie. Elle peut tre utilise avec le paramtre sinon si, et le modificateur ne pas. Le modificateur /i ne fonctionne pas sur cette condition. Voir le script 33.

si [[[[ne pas] défini <variable> <ordre>

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19

@écho de
ensemble "Def1="
ensemble "Def2=abcd"
si défini Def1 (
    écho Def1 est dfinie.
) autre (
    écho Def1 n&#39;est pas dfinie.
)
si défini Def2 (
    écho Def2 est dfinie.
) autre (
    écho Def2 n&#39;est pas dfinie.
)
si ne pas défini Def3 (
    écho Def3 n&#39;est pas dfinie.
) autre (
    écho Def3 est dfinie.
)
pause
If_Defined

III-D. La condition errorlevel

La condition errorlevel permet de tester si le code d&#39;erreur de la dernire commande excute est gal ou suprieur au nombre donn en . Le code d&#39;erreur est un nombre renvoy par une commande pour donner des informations sur le droulement de son excution, il est aussi accessible via la variable ErrorLevel. En gnral, le code d&#39;erreur est 0 si aucune erreur ne s&#39;est produite; et il est gal ou suprieur 1 si une erreur s&#39;est produite, chaque code d&#39;erreur correspondant une erreur prcise. Le nom de variable ErrorLevel est un nom de variable rserv, vous pouvez la modifier en l&#39;crasant avec une nouvelle valeur, cependant, elle prendra la valeur donne jusqu&#39; la fin du script. Attention toutefois, il arrive que des commandes ne modifient pas la variable ErrorLevel ou bien qu&#39;elle lui donne toujours le code 0, ceci est souvent d de mauvaises pratiques de programmation, fiez-vous des codes d&#39;erreurs connues et ayant une valeur concrte, ne traitez pas les autres, pour ce faire, consultez le manuel ou l&#39;aide de la commande concerne. Si le modificateur ne pas est utilis, la seras excute seulement si ErrorLevel est infrieur l&#39;. Le modificateur /i n&#39;est pas support par la condition errorlevel .

si [[[[ne pas] errorlevel <oprande> <ordre>

1.
2
3
4
5
6
7.
8
9
dix.
11
12

@écho de

setlocal
ensemble "TestError1=Un petit test"
si ne pas errorlevel 1 écho Aucune erreur dans la premire commande.
echo.
ensemble /a "TestError2=09"
echo.
si errorlevel 1 écho Le code d&#39;erreur des nombres invalides est %ErrorLevel%.
pause

endlocal
If_Errolevel

III-E. La condition cmdextversion

La condition cmdextversion permet de tester si le numro de version des extensions de commande est gal ou suprieur au nombre donn en . Le numro de version des extensions de commande est prendre en compte, car selon la version des extensions, le traitement des commandes peut tre modifi. Reportez-vous l&#39;aide concernant les commandes cites dans le tableau 7 pour plus de dtails. Chaque commande modifie l&#39;est d&#39;une manire qui lui est propre; ainsi la commande assoc ne sera pas modifie de la mme manire que la commande début, tout simplement parce qu&#39;elle n&#39;excute pas du tout la mme opration.

DEL ou ERASE

COLOR

CD ou CHDIR

MD ou MKDIR

PROMPT

PUSHD

POPD

ENSEMBLE

SETLOCAL

ENDLOCAL

IF

POUR

CALL

SHIFT

GOTO

START

ASSOC

FTYPE

Tableau 7: Commandes soumises aux extensions

La condition cmdextversion est toujours fausse si les extensions de commande sont dsactives; la premire version des extensions est la version 1 et le numro de version est incrment de 1 chaque nouvelle version. Si le numro de version des extensions est gal ou suprieur la valeur donne dans la condition cmdextversion alors la condition est vraie; les extensions de commande tant rtrocompatibles d&#39;une version l&#39;autre. Si le modificateur ne pas est utilis, la condition est vraie si le numro de version des extensions de commande est infrieur au nombre donn en . La condition cmdextversion ne prend pas le modificateur /i. Le tableau 8 donne la liste des rvisions d&#39;extensions de commande en fonction du systme d&#39;exploitation.

Numro de version

Compatibilit

1

Windows 2000.

2

Tous les systmes NT XP et suprieur.

Tableau 8: Rvisions des extensions de commande

si [[[[ne pas] cmdextversion <oprande> <ordre>

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19

@écho de

setlocal enableextensions
si ne pas cmdextversion 1 (
    écho CmdExtVersion 1:  ne pas Detected.
) autre (
    écho CmdExtVersion 1:  Detected. 
)
si cmdextversion 2 (
    écho CmdExtVersion 2:  Detected.
) autre (
    écho CmdExtVersion 2:  ne pas Detected. 
)
si cmdextversion 3 (
    écho CmdExtVersion 3:  Detected.
) autre (
    écho CmdExtVersion 3:  ne pas Detected. 
)
pause
If_CmdExtVersion

III-F. La condition

La condition permet d&#39;effectuer des comparaisons sur des chanes et des nombres. La comparaison de chanes est effectue au moyen d&#39;un XOR au niveau du bit entre chaque octet d&#39;une chane puis les rsultats obtenus sur les diffrentes chanes sont compars numriquement. Si les deux chanes ne sont constitues que de chiffres alors elles sont transtypes en nombre puis values numriquement. Les comparateurs, pris en compte par la condition , sont lists dans le tableau 9. La condition prend les modificateurs ne pas et /i. Sa syntaxe est la suivante, si les chanes contiennent des espaces, elles doivent tre places entre guillemets.

si [/i] [[[[ne pas] [« ]<chane1>[« ] <comparateur> [« ]<chane2>[« ] <cmd>

Comparateur

La description

EQU

EQUal, la condition est vraie si les deux chanes sont gales.

NEQ

Not EQual, la condition est vraie si les deux chanes sont diffrentes.

LSS

LeSS, la condition est vraie si chane1 est infrieure chane2.

LEQ

Less or EQual, la condition est vraie si chane1 est infrieure ou gale chane2.

GTR

GreaTeR, la condition est vraie si chane1 est suprieure chane2.

GEQ

Greater or EQual, la condition est vraie si chane1 est suprieure ou gale chane2.

Tableau 9: Oprateurs de comparaison

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46
47
48.
49
50
51.
52
53
54
55
56.
57
58
59
60.
61.
62
63.
64.
65.
66.
67.
68.
69
70.
71.
72.
73.
74.
75.

@écho de
cls
ensemble "Chane1=Un Petit test"

ensemble /a "C1X=0x55^0x6E^0x20^0x50^0x65^0x74^0x69^0x74^0x20^0x74^0x65^0x73^0x74"
ensemble "Chane2=Un petit test"

ensemble /a "C2X=0x55^0x6E^0x20^0x70^0x65^0x74^0x69^0x74^0x20^0x74^0x65^0x73^0x74"
ensemble "Chane3=Un grand test"

ensemble /a "C3X=0x55^0x6E^0x20^0x67^0x72^0x62^0x6E^0x64^0x20^0x74^0x65^0x73^0x74"
ensemble "Chane4=41"
ensemble "Chane5=12"
écho               Chane 1         Chane 2          Chane 3
écho =============================================================
écho Chane        %Chane1%    %Chane2%    %Chane3%
écho évaluation    %C1X%              %C2X%               %C3X%
echo.
si "%Chane1%" GTR "%Chane2%" (
    écho "%Chane1%" est suprieur  "%Chane2%".
) autre si "%Chane1%" EQU "%Chane2%" (
    écho "%Chane1%" est gal  "%Chane2%".
) autre si "%Chane1%" LSS "%Chane2%" (
    écho "%Chane1%" est infrieur  "%Chane2%".
)
si /i "%Chane1%" GTR "%Chane2%" (
    écho "%Chane1%" est suprieur  "%Chane2%".
) autre si /i "%Chane1%" EQU "%Chane2%" (
    écho "%Chane1%" est gal  "%Chane2%".
) autre si /i "%Chane1%" LSS "%Chane2%" (
    écho "%Chane1%" est infrieur  "%Chane2%".
)
si "%Chane1%" GTR "%Chane3%" (
    écho "%Chane1%" est suprieur  "%Chane3%".
) autre si "%Chane1%" EQU "%Chane3%" (
    écho "%Chane1%" est gal  "%Chane3%".
) autre si "%Chane1%" LSS "%Chane3%" (
    écho "%Chane1%" est infrieur  "%Chane3%".
)
si /i "%Chane1%" GTR "%Chane3%" (
    écho "%Chane1%" est suprieur  "%Chane3%".
) autre si /i "%Chane1%" EQU "%Chane3%" (
    écho "%Chane1%" est gal  "%Chane3%".
) autre si /i "%Chane1%" LSS "%Chane3%" (
    écho "%Chane1%" est infrieur  "%Chane3%".
)
si "%Chane3%" GTR "%Chane2%" (
    écho "%Chane3%" est suprieur  "%Chane2%".
) autre si "%Chane3%" EQU "%Chane2%" (
    écho "%Chane3%" est gal  "%Chane2%".
) autre si "%Chane3%" LSS "%Chane2%" (
    écho "%Chane3%" est infrieur  "%Chane2%".
)
si /i "%Chane3%" GTR "%Chane2%" (
    écho "%Chane3%" est suprieur  "%Chane2%".
) autre si /i "%Chane3%" EQU "%Chane2%" (
    écho "%Chane3%" est gal  "%Chane2%".
) autre si /i "%Chane3%" LSS "%Chane2%" (
    écho "%Chane3%" est infrieur  "%Chane2%".
)
echo.
echo.
écho               Chane 4    Chane 5         
écho =============================================================
écho Chane        %Chane4%          %Chane5%
echo.
si %Chane4% GTR %Chane5% (
    écho %Chane4% est suprieur  %Chane5%.
) autre si %Chane4% EQU %Chane5% (
    écho %Chane4% est gal  %Chane5%.
) autre si %Chane4% LSS %Chane5% (
    écho %Chane4% est infrieur  %Chane5%.
)
echo.
pause
If_op1_comp_op2

III-G. La condition ""==""▲

La condition ""=="" permet de tester une galit entre des chanes de caractres. Les chanes doivent tre places entre guillemets si elles sont susceptibles de contenir des espaces. Cette condition prend les modificateurs ne pas et /i.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20

@écho de
cls
ensemble "Un=Une Chane"
ensemble "Deux=une chane"
si "%Un%"=="%Deux%" (
    écho If:      "%Un%"    est gale     "%Deux%".
) autre (
    écho If:      "%Un%" n&#39;est pas gale  "%Deux%".
)
si ne pas "%Un%"=="%Deux%" (
    écho If ne pas:  "%Un%" n&#39;est pas gale  "%Deux%".
) autre (
    écho If ne pas:  "%Un%"    est gale     "%Deux%".
)
si /i "%Un%"=="%Deux%" (
    écho If /i:   "%Un%"    est gale     "%Deux%".
) autre (
    écho If /i:   "%Un%" n&#39;est pas gale  "%Deux%".
)
pause
If_str1_comp_str2

III-H. Mise en application de la commande if▲

Dans cette section, nous allons reprendre le script 29 qui permettait de transformer un entier en sa reprsentation hexadcimale en notation en complment deux. Grce la commande si, nous allons faire en sorte de traiter les nombres ngatifs et positifs avec la mme fonction de calcul et d&#39;afficher le rsultat dans une forme hexadcimale correcte.

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46
47
48.
49
50
51.
52
53
54
55
56.
57
58
59
60.
61.
62
63.
64.
65.
66.
67.
68.
69
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99
100
101.
102.
103.
104
105
106.
107.
108.
109.
110.
111.
112.
113.
114.

@écho de

setlocal

ensemble /p "SInt32=Entrez un nombre entre -2147483648 et 2147483647:    "

ensemble /a "SInt32"



ensemble "NegNum=false"



si %SInt32% LSS 0 (
    ensemble /a "SInt32=~SInt32"
    ensemble "NegNum=true"
)


ensemble /a "Nibble0= SInt32 %% 16","HighOrder0= SInt32 / 16"
ensemble /a "Nibble1=HighOrder0 %% 16","HighOrder1=HighOrder0 / 16"
ensemble /a "Nibble2=HighOrder1 %% 16","HighOrder2=HighOrder1 / 16"
ensemble /a "Nibble3=HighOrder2 %% 16","HighOrder3=HighOrder2 / 16"
ensemble /a "Nibble4=HighOrder3 %% 16","HighOrder4=HighOrder3 / 16"
ensemble /a "Nibble5=HighOrder4 %% 16","HighOrder5=HighOrder4 / 16"
ensemble /a "Nibble6=HighOrder5 %% 16"
ensemble /a "Nibble7=HighOrder5 / 16"


si "%NegNum%"=="true" (
    ensemble /a "Nibble0=15 - Nibble0"
    ensemble /a "Nibble1=15 - Nibble1"
    ensemble /a "Nibble2=15 - Nibble2"
    ensemble /a "Nibble3=15 - Nibble3"
    ensemble /a "Nibble4=15 - Nibble4"
    ensemble /a "Nibble5=15 - Nibble5"
    ensemble /a "Nibble6=15 - Nibble6"
    ensemble /a "Nibble7=15 - Nibble7"
)

si %Nibble0% GTR 9 (
    si %Nibble0% EQU dix ensemble "Nibble0=A"
    si %Nibble0% EQU 11 ensemble "Nibble0=B"
    si %Nibble0% EQU 12 ensemble "Nibble0=C"
    si %Nibble0% EQU 13 ensemble "Nibble0=D"
    si %Nibble0% EQU 14 ensemble "Nibble0=E"
    si %Nibble0% EQU 15 ensemble "Nibble0=F"
)
si %Nibble1% GTR 9 (
    si %Nibble1% EQU dix ensemble "Nibble1=A"
    si %Nibble1% EQU 11 ensemble "Nibble1=B"
    si %Nibble1% EQU 12 ensemble "Nibble1=C"
    si %Nibble1% EQU 13 ensemble "Nibble1=D"
    si %Nibble1% EQU 14 ensemble "Nibble1=E"
    si %Nibble1% EQU 15 ensemble "Nibble1=F"
)
si %Nibble2% GTR 9 (
    si %Nibble2% EQU dix ensemble "Nibble2=A"
    si %Nibble2% EQU 11 ensemble "Nibble2=B"
    si %Nibble2% EQU 12 ensemble "Nibble2=C"
    si %Nibble2% EQU 13 ensemble "Nibble2=D"
    si %Nibble2% EQU 14 ensemble "Nibble2=E"
    si %Nibble2% EQU 15 ensemble "Nibble2=F"
)
si %Nibble3% GTR 9 (
    si %Nibble3% EQU dix ensemble "Nibble3=A"
    si %Nibble3% EQU 11 ensemble "Nibble3=B"
    si %Nibble3% EQU 12 ensemble "Nibble3=C"
    si %Nibble3% EQU 13 ensemble "Nibble3=D"
    si %Nibble3% EQU 14 ensemble "Nibble3=E"
    si %Nibble3% EQU 15 ensemble "Nibble3=F"
)
si %Nibble4% GTR 9 (
    si %Nibble4% EQU dix ensemble "Nibble4=A"
    si %Nibble4% EQU 11 ensemble "Nibble4=B"
    si %Nibble4% EQU 12 ensemble "Nibble4=C"
    si %Nibble4% EQU 13 ensemble "Nibble4=D"
    si %Nibble4% EQU 14 ensemble "Nibble4=E"
    si %Nibble4% EQU 15 ensemble "Nibble4=F"
)
si %Nibble5% GTR 9 (
    si %Nibble5% EQU dix ensemble "Nibble5=A"
    si %Nibble5% EQU 11 ensemble "Nibble5=B"
    si %Nibble5% EQU 12 ensemble "Nibble5=C"
    si %Nibble5% EQU 13 ensemble "Nibble5=D"
    si %Nibble5% EQU 14 ensemble "Nibble5=E"
    si %Nibble5% EQU 15 ensemble "Nibble5=F"
)
si %Nibble6% GTR 9 (
    si %Nibble6% EQU dix ensemble "Nibble6=A"
    si %Nibble6% EQU 11 ensemble "Nibble6=B"
    si %Nibble6% EQU 12 ensemble "Nibble6=C"
    si %Nibble6% EQU 13 ensemble "Nibble6=D"
    si %Nibble6% EQU 14 ensemble "Nibble6=E"
    si %Nibble6% EQU 15 ensemble "Nibble6=F"
)
si %Nibble7% GTR 9 (
    si %Nibble7% EQU dix ensemble "Nibble7=A"
    si %Nibble7% EQU 11 ensemble "Nibble7=B"
    si %Nibble7% EQU 12 ensemble "Nibble7=C"
    si %Nibble7% EQU 13 ensemble "Nibble7=D"
    si %Nibble7% EQU 14 ensemble "Nibble7=E"
    si %Nibble7% EQU 15 ensemble "Nibble7=F"
)

ensemble "LSW=%Nibble3%%Nibble2%%Nibble1%%Nibble0%"

ensemble "MSW=%Nibble7%%Nibble6%%Nibble5%%Nibble4%"

écho 0x%MSW%%LSW%

endlocal
pause

Ce script sera un script tmoin que nous ferons voluer tout au long de ce document, il nous permettra de comparer les diffrentes approches et ce qu&#39;elles impliquent comme contrainte d&#39;utilisation.

En son tat actuel, ce script est gourmand en ressource systme, car chaque ligne de commande correspond un appel vers l&#39;interprteur augmentant d&#39;autant son temps de traitement. Les boucles pour devraient nous permettre de rduire considrablement son cot en temps d&#39;excution et la taille du script par la mme occasion.

Un script batch s&#39;excute toujours de manire linaire, du dbut vers la fin, et moins que l&#39;on ne redirige son excution, ce comportement reste inchang. Il existe plusieurs possibilits pour rediriger l&#39;excution d&#39;un script telles que: les labels, les sauts, les appels de fonction et les sorties.

IV-A. Les labels▲

Les labels sont des adresses relatives se prsentant sous forme de chanes de caractres prfixes par : et termines par un caractre blanc (l&#39;espace, la tabulation ou le retour la ligne). Ces adresses relatives pointent vers le premier caractre situ aprs le retour la ligne qui termine le label. Elles peuvent tre utilises pour adresser une portion de code. Chaque nom de label devrait tre unique dans le script. La syntaxe d&#39;un label est la suivante, o est le nom du label:

:<Étiquette>

IV-B. Les sauts▲

The command goto effectue un saut inconditionnel vers le label spcifi en paramtre, permettant ainsi de continuer l&#39;excution du programme dans une portion de code situe n&#39;importe o dans le script. Une fois le saut effectu, l&#39;excution continue la ligne qui suit le label spcifi:

goto [[[[:]<Étiquette>

1.
2
3
4
5
6
7.
8

@écho de

goto :MonLabel
écho Une phrase qui ne sera jamais affiche.

:MonLabel
écho Une phrase qui sera affiche.
pause
Goto

Dans le script 39, la commande echo Une phrase qui ne sera jamais affiche. n&#39;est pas traite, l&#39;excution tant redirige par la commande goto:MonLabel vers la ligne suivant le label :MonLabel soit la commande echo Une phrase qui sera affiche.

IV-C. Contexte de commande▲

L&#39;excution de l&#39;interprteur ou d&#39;un script s&#39;effectue dans un processus hte auquel le systme d&#39;exploitation alloue un espace mmoire. Cet espace mmoire est appel la pile. Une pile est une zone de mmoire dans laquelle les donnes sont places les unes la suite des autres. Les donnes qui y sont places doivent tre rcupres dans un ordre particulier: la dernire donne place doit tre la premire tre rcupre. Sur cette pile, le systme y place ce que l&#39;on appelle un contexte.

Lors de sa cration, le contexte se voit attribuer, par le systme, une srie de variables: les variables d&#39;environnement du systme, des variables contenant la commande et les paramtres de la commande ayant gnr le contexte et une adresse de sortie du contexte. Ainsi cr, le contexte reprsente l&#39;environnement dans lequel le script va s&#39;excuter en lui permettant de disposer de donnes qui lui sont propres. chaque nouvelle excution d&#39;un script ou d&#39;une commande, l&#39;interprteur cre un nouveau contexte et le place sur la pile. Ce nouveau contexte est appel contexte descendant.

Les variables d&#39;environnement sont hrites du systme lors de la cration du processus hte et se propagent par ascendance successive aux diffrents contextes descendants. Les variables contenant la commande et les arguments d&#39;appels, elles, sont propres au contexte et ne se propagent jamais aux contextes descendants. L&#39;adresse de sortie du contexte n&#39;est pas accessible en tant que variable et, tout comme les arguments d&#39;appel, est propre au contexte. Son rle est plus amplement dtaill dans le reste du chapitre.

Certaines commandes s&#39;excutent dans le contexte en cours alors que d&#39;autres crent leurs propres contextes. C&#39;est, en partie, ce qui fait la diffrence entre commande interne et externe: les commandes internes sont en fait des fonctions internes de l&#39;interprteur qu&#39;il est possible d&#39;appeler via un alias de type nom de commande, alors que les commandes externes sont des excutables distincts de l&#39;interprteur. L&#39;excution d&#39;une commande externe ou d&#39;un script gnrera toujours un nouveau contexte. Les commandes internes s&#39;excutent toujours dans le contexte courant. Il faut cependant noter que les commandes internes, mme si elles excutent toujours leurs fonctions principales dans le contexte courant, peuvent crer des contextes descendants afin d&#39;excuter certaines fonctions comme la boucle pour qui gnre un contexte initial dans lequel se trouve l&#39;ensemble traiter et un contexte secondaire, cr chaque itration de la boucle, dans lequel s&#39;opre le traitement.

IV-C-1. La porte des variables▲

Si le concept de contexte de commande est si important, c&#39;est qu&#39;il influe grandement sur l&#39;utilisation des variables. En effet, chaque contexte est une fraction de la pile qui n&#39;est pas accessible lorsque l&#39;excution s&#39;opre depuis un contexte ascendant. Les variables se propagent par ascendance; c&#39;est–dire que lorsqu&#39;un nouveau contexte est cr, il hrite des variables (et de leurs valeurs) du contexte ascendant (celui partir duquel il a t cr). Si une variable est modifie dans un contexte descendant, sa valeur restera inchange dans le contexte ascendant. Ainsi, faire passer une variable vers un contexte descendant est simple (il suffit de crer le contexte), mais l&#39;inverse s&#39;avre plus compliqu, car il n&#39;est pas possible de modifier une valeur dans un contexte ascendant.

L&#39;interprteur supporte l&#39;expansion retarde des variables qui permet, dans une certaine mesure, de faire passer une valeur vers un contexte ascendant. Pour cela, le processus hte, lorsque l&#39;expansion retarde est active, alloue une seconde zone de mmoire qui prend la forme d&#39;un tas qui est accessible depuis n&#39;importe quel contexte. Contrairement la pile, il est possible, avec le tas, d&#39;y placer et rcuprer les donnes dans n&#39;importe quel ordre. chaque fois qu&#39;une variable est cre ou modifie, elle est place la fois dans le contexte (autrement dit sur la pile) et dans le tas. Pour accder aux variables dont l&#39;expansion est retarde, il faut utiliser le symbole ! au lieu du symbole % lors de leur expansion. Ainsi la variable prendra la dernire valeur qui lui a t attribue pendant l&#39;excution et non la valeur qu&#39;elle possde dans le contexte en cours. L&#39;expansion retarde des variables sera plus amplement aborde dans le chapitre VIL&#39;expansion retarde des variables.

IV-D. Les fonctions▲

Les fonctions sont des portions de code isoles, commenant par un label et finissant par un saut une adresse spcifique: l&#39;adresse de retour. La vraie diffrence avec une simple portion de code rside dans le fait qu&#39;un nouveau contexte est cr, permettant ainsi aux fonctions de disposer de paramtres de commande et, dans certains cas, d&#39;un code de sortie.

IV-D-1. L&#39;appel de fonction▲

The command appel permet d&#39;effectuer des appels de fonction. Elle a la particularit de crer un contexte dans lequel va s&#39;excuter la fonction appele (la portion de code); lors de la cration du contexte descendant, une adresse de retour et les arguments d&#39;appel vont tre empils. La syntaxe de la commande appel est la suivante, o est le nom de la fonction appeler et est le ou les paramtres passer la fonction.

appel :<étiquette> [[[[<paramtre> […]]

Lors d&#39;un appel une fonction, si l&#39;excution est redirige vers une autre adresse que l&#39;adresse de retour et que, par la suite, d&#39;autres appels sont effectus vers cette mme fonction, alors la premire adresse ne sera pas dpile, occasionnant une fuite de mmoire. Si un script comporte ce cas, son excution peut tre stoppe par l&#39;interprteur (si l&#39;utilisation de la pile atteint 90%) comme le montre le script 40.

1.
2
3
4
5

@écho de
:LabelUn
appel :LabelDeux
:LabelDeux
goto :LabelUn
Dep_Stack

IV-D-2. Sortie de fonction▲

The command goto prend aussi le label :eof (End Of File), qui prend la valeur de l&#39;adresse de retour du contexte en cours, soit la ligne se trouvant immdiatement aprs le dernier appel effectu.

The command goto n&#39;ajoute rien dans la pile, ainsi l&#39;excution d&#39;un goto ne peut occasionner de fuite de mmoire. Dans le cas prcis de l&#39;excution d&#39;un goto:eof, la commande goto incrmente le pointeur de pile de la taille totale des adresses des arguments d&#39;appel et de la taille de l&#39;adresse de retour, permettant la pile de revenir l&#39;tat d&#39;avant l&#39;appel, puis effectue un saut inconditionnel l&#39;adresse de retour, soit la ligne suivant le dernier appel. Ainsi, si l&#39;on modifie le script 40 de la manire suivante (script 41), on obtient un script qui ne finit jamais, car il n&#39;y a ni fuite de mmoire (chaque appel de la fonction :LabelDeux finished by goto:eof), ni point de sortie (il y aura toujours une commande excuter, l&#39;excution revient toujours au :LabelUn). Seul l&#39;appui sur les touches Ctrl+C permet de quitter le script.

1.
2
3
4
5
6
7.
8
9
dix.

@écho de

ensemble /a "Counter=0"
:LabelUn
appel :LabelDeux
ensemble /a "Counter+=1"
goto :LabelUn
:LabelDeux
écho %Counter%
goto :eof

IV-E. Les paramtres de commande▲

Ils sont passs au contexte lors de sa cration et sont accessibles sous la forme de variables spciales: %n, n tant le numro d&#39;index du paramtre. En effet, chaque contexte tant gnr suite l&#39;appel d&#39;un script, d&#39;une fonction ou d&#39;une commande, il possde une commande d&#39;appel et, la plupart du temps, de paramtres d&#39;appel. L&#39;index %0 contient le nom du script, de la fonction ou de la commande, l&#39;index %1 contient le paramtre 1, l&#39;index %2 contient le paramtre 2 et ainsi de suite. Le paramtre %* expanse tous les paramtres passs au contexte (%0 n&#39;est pas un paramtre, mais une commande d&#39;appel et n&#39;est donc pas renvoye par %*). Exemple avec le script 42:

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15

@écho de

appel :MonLabel Param1 Param2
pause



goto :eof

:MonLabel
écho %*
écho %0
écho %1
écho %2
goto :eof
Call_Args

L&#39;utilisation des paramtres suit plusieurs rgles:

  • les paramtres ne sont pas limits en nombre dans la commande d&#39;appel, mais la rgle des 2048/4096 caractres maximum par ligne de commande s&#39;applique;
  • par souci de compatibilit avec les systmes Windows XP et antrieurs, il est prfrable de ne pas utiliser des paramtres avec un index suprieur 9, qui restent cependant accessibles via la commande décalage (voir section IV.E.2La commande shift).

IV-E-1. Les modificateurs de paramtres de commande▲

Les paramtres de commande supportent plusieurs modificateurs permettant de les parser, en voici la liste exhaustive:

Modificateur

La description

%~1

résultats %1 en supprimant les guillemets (") de dbut et de fin.

%~f1

renvoie le chemin d&#39;accs vrifi du fichier dsign par %1, si le fichier n&#39;est pas trouv, alors ce modificateur s&#39;expanse en une chane vide.

%~d1

renvoie la lettre de lecteur du fichier dsign par %1.

%~p1

renvoie le chemin d&#39;accs du fichier dsign par %1.

%~n1

renvoie le nom du fichier dsign par %1.

%~x1

renvoie l&#39;extension du fichier dsign par %1.

%~s1

renvoie le chemin d&#39;accs, sous forme de noms courts, du fichier dsign par %1.

%~a1

renvoie les attributs du fichier dsign par %1.

%~t1

renvoie la date et l&#39;heure de cration du fichier dsign par %1.

%~z1

renvoie la taille du fichier dsign par %1.

%~$:1

est parcourue la recherche d&#39;occurrence de %1, si aucune occurrence de %1 n&#39;est trouve ou que n&#39;est pas dfini dans le contexte en cours, alors ce modificateur s&#39;expanse en une chane vide. Oui est compos de plusieurs chanes, elles doivent tre spares par des points-virgules (;) afin que le modificateur puisse les distinguer correctement.

Tableau 10: Les modificateurs de paramtres de commande.

Les modificateurs de paramtres de commande fonctionnent pour tous les index. Ils peuvent tre utiliss conjointement pour obtenir plusieurs informations en mme temps, comme le montre le script 43:

1.
2
3
4
5
6
7.
8
9

@écho de

cls
appel :MonLabel %cmdcmdline%
pause
goto :eof
:MonLabel
écho %~dpnx€ComSpec:1
goto :eof
Modif_Call_Args

IV-E-2. La commande shift▲

The command décalage permet de dcaler l&#39;index de tous les paramtres de -1, afin d&#39;accder aux index suprieurs neuf, ou de crer un mcanisme de gestion des paramtres (voir la mise en application de ce chapitreMise en application des contextes). Si les extensions de commande sont actives, la commande décalage prend le paramtre /n, o n est le numro d&#39;index partir duquel commence le dcalage des paramtres, tous les index gaux ou suprieurs n seront dcals de -1.

décalage [/n]

Dans le script 44, le commande shift /1 permet d&#39;accder au deuxime paramtre via l&#39;index 1:.

1.
2
3
4
5
6
7.
8
9

@écho de
cls
appel :MonLabel "rien" %cmdcmdline%
pause
sortie /b
:MonLabel
décalage /1
écho %~dpnx€ComSpec:1
goto :eof
Shift_Call_Args

IV-F. Les sorties▲

La sortie d&#39;un contexte ou d&#39;un processus peut s&#39;effectuer via les commandes sortie et goto:eof. Dans le cas de goto:eof, si tous les contextes ont correctement t dpils, alors la dernire adresse dpile est:

  • soit l&#39;adresse de sortie du processus dans le cas d&#39;un script appel en cliquant dessus;
  • soit l&#39;adresse de retour l&#39;interprteur si le script a t lanc depuis celui-ci.

The command sortie, elle, permet de sortir du processus hte, quel que soit le nombre de contextes empils. Si la commande sortie est utilise avec le paramtre /b, alors la sortie s&#39;effectuera l&#39;adresse de sortie du contexte et non l&#39;adresse de sortie du processus hte. L&#39;intrt de la commande sortie est qu&#39;un code numrique de sortie peut tre spcifi, contrairement goto:eof. La syntaxe de la commande exit est la suivante, o est le code de sortie.

sortie [/b] [[[[<CodeSortie>]

Dans le script 45, la sortie de la fonction :LabelDeux s&#39;effectue l&#39;aide d&#39;un goto:eof et la sortie de la fonction :LabelQuatre s&#39;effectue l&#39;aide d&#39;exit /b; dans les deux cas, le retour vers la procdure appelante s&#39;opre correctement, car c&#39;est la bonne adresse de retour qui est dpile. Dans la fonction :LabelSix du script 45, la commande exit /b provoque la fin du script, car la fonction :LabelSix a t appele avec la commande goto:LabelSix qui n&#39;a rien empil. Comme tous les contextes prcdents ont t dpils correctement, seule la dernire adresse de retour subsiste. Cette adresse correspond l&#39;adresse de retour l&#39;interprteur si le script a t appel depuis celui-ci ou l&#39;adresse de sortie du processus, si le script a t appel par un double-clic.

1.
2
3
4
5
6
7.
8
9
dix.
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

@écho de
cls
ensemble /a "CounterGoto=0"
ensemble /a "CounterExit=0"
ensemble /a "CounterCounter=0"
:LabelUn
appel :LabelDeux
ensemble /a "CounterGoto+=1"
écho CounterGoto: %CounterGoto% sur affichage Goto 1.
si %CounterGoto% EQU 6 goto :LabelTrois
goto :LabelUn
:LabelDeux
ensemble /a "CounterGoto+=1"
écho CounterGoto: %CounterGoto% sur affichage Goto 2
goto :eof

:LabelTrois
appel :LabelQuatre
ensemble /a "CounterExit+=1"
écho CounterExit: %CounterExit% sur affichage Sortie 1.
si %CounterExit% EQU 6 goto :LabelCinq
goto :LabelTrois
:LabelQuatre
ensemble /a "CounterExit+=1"
écho CounterExit: %CounterExit% sur affichage Sortie 2
sortie /b

:LabelCinq
goto :LabelSix
ensemble /a "CounterCounter+=1"
écho CounterCounter: %CounterCounter% sur affichage Counter 1.
si %CounterCounter% EQU 6 sortie /b
goto :LabelCinq
:LabelSix
ensemble /a "CounterCounter+=1"
écho CounterCounter: %CounterCounter% sur affichage Counter 2.
sortie /b
Sortie

IV-G. Code de sortie▲

Comme expliqu prcdemment, un code de sortie peut tre spcifi pour une fonction ou pour un script. Cela se fait via la commande sortie [/b] o est un code de sortie numrique. Les codes de sortie sont rgis par les mmes rgles que les nombres entiers et sont cods sur 32 bits en arithmtique signe. Ce code de sortie est fix dans la variable ErrorLevel afin de pouvoir tre utilis par la suite. Exemple avec le script 46:

1.
2
3
4
5
6
7.
8
9

@écho de

écho %ErrorLevel%
appel :UnLabel
écho %ErrorLevel%
pause
sortie /b
:UnLabel
sortie /b 1
output_code

IV-H. Script batch et adresse de retour▲

L&#39;appel d&#39;un script depuis l&#39;interprteur ou en cliquant dessus gnre toujours un contexte complet. Cependant l&#39;appel d&#39;un script en ligne de commande depuis un autre script gnre un contexte ne possdant pas d&#39;adresse de retour. Exemple avec le script 47:

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18

@écho de

si exister test.bat del /q test.bat

appel :WriteTestBat >>test.bat

test.bat

écho Return  %~nx0.
del /q test.bat
pause
sortie /b

:WriteTestBat
écho @écho de
écho écho Une phrase affiche dans test.bat
écho pause
goto :eof

Lorsqu&#39;on excute le script 47, celui-ci cre un second script, test.bat. L&#39;appel en ligne de commande Test.bat affiche alors Une phrase affiche depuis test.bat et met en pause l&#39;excution. Lorsqu&#39;on appuie sur une touche, cela provoque la fin des deux scripts. En effet, quand l&#39;interprteur arrive la fin d&#39;un script et que celui-ci ne se termine pas par goto :eof ou sortie [/b], il effectue de lui-mme le saut l&#39;adresse de retour. Sauf que l&#39;appel de test.bat n&#39;a pas empil d&#39;adresse de retour et de ce fait, l&#39;adresse qui est dpile est celle du premier script. Pour parer ce problme, il faut s&#39;assurer que l&#39;adresse de retour soit effectivement empile en utilisant la commande appel. Ainsi, en modifiant le script 47 de la manire suivante (script 48), l&#39;appel et la sortie s&#39;effectuent sans erreur.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18

@écho de

si exister test.bat del /q test.bat

appel :WriteTestBat >>test.bat

appel test.bat

écho Return  %~nx0.
del /q test.bat
pause
sortie /b

:WriteTestBat
écho @écho de
écho écho Une phrase affiche dans test.bat
écho pause
goto :eof

IV-I. La commande start▲

The command début permet de lancer un script ou une commande dans un nouveau processus, permettant ainsi d&#39;excuter des commandes dans un environnement modifi. Ainsi, toute variable cre ou modifie dans le script appelant est passe ce nouveau processus.

Syntaxe de la commande start

Sélectionnez

début ["["["["<légende>"][/d[/d[/d[/d<chemin>] [/i] [/min] [/max]    [/separate[/separate[/separate[/separate|/shared][/low[/low
      [/low|/normal|/high|/realtime|/abovenormal|/belownormal][/affinity[/affinity[/affinity[/affinity<hexa>]
      [/wait] [/b]    [[[[<ordre>][[[[<paramtres>]

Paramtres

Descriptions

Titre de la fentre.

/d

Spcifie que le chemin d&#39;accs donn par est le rpertoire de dpart.

Chemin d&#39;accs du rpertoire de dpart.

/b

Lance l&#39;application dans la fentre courante (en tche de fond). L&#39;arrt par Ctrl+C est remplac par Ctrl+Pause.

/i

Le nouveau contexte sera le contexte original du processus hte et non le contexte en cours.

/min

Dmarrer dans une fentre rduite.

/max

Dmarrer dans une fentre agrandie.

/separate

Dmarrer les programmes 16 bits dans un espace mmoire distinct. Ne fonctionne pas sur les systmes 64 bits.

/shared

Dmarrer les programmes 16 bits dans un espace mmoire partag. Ne fonctionne pas sur les systmes 64 bits.

/low

Dmarrer l&#39;application dans la classe de priorit IDLE.

/normal

Dmarrer l&#39;application dans la classe de priorit NORMAL.

/high

Dmarrer l&#39;application dans la classe de priorit HIGH.

/realtime

Dmarrer l&#39;application dans la classe de priorit REALTIME.

/abovenormal

Dmarrer l&#39;application dans la classe de priorit ABOVENORMAL.

/belownormal

Dmarrer l&#39;application dans la classe de priorit BELOWNORMAL.

/affinity

La nouvelle application aura le masque d&#39;affinit de processeur spcifi, exprim en tant que valeur hexadcimale.

Affinit du processus sous forme de valeur hexadcimale.

/wait

Lancer la commande et attendre qu&#39;elle soit finie pour continuer l&#39;excution. S&#39;il s&#39;agit d&#39;une commande interne ou d&#39;un fichier batch, la fentre reste ouverte aprs l&#39;excution de la commande.

Commande excuter.

Paramtres passer la commande.

Tableau 11: Les paramtres de la commande start.

Le script 49 appelle une nouvelle instance de lui-mme avec le paramtre foo aprs avoir dfini la variable X, la seconde instance affiche bien la valeur de X alors qu&#39;elle n&#39;a pas dclar X. Notez bien qu&#39;il s&#39;agit d&#39;un nouveau processus, il est donc possible de le quitter avec la commande sortie sans aucun paramtre.

1.
2
3
4
5
6
7.
8
9
dix.

@écho de
si "%1"=="foo" goto SecondInstance
ensemble "X=bar"
début %~nx0 foo
pause
sortie /b
:SecondInstance
écho %X%
pause
sortie

Premire instance:

start_0

Seconde instance:

start_1

Si l&#39;on modifie le script 49 en ajoutant le paramtre /i dans l'ordre début (script 50), alors le nouveau processus sera cr en hritant du contexte original du processus hte dans lequel la variable X n&#39;a pas t dclare.

1.
2
3
4
5
6
7.
8
9
dix.

@écho de
si "%1"=="foo" goto SecondInstance
ensemble "X=bar"
début /i %~nx0 foo
pause
sortie /b
:SecondInstance
écho %X%
pause
sortie

Premire instance:

start_i_0

Seconde instance:

start_i_1

Une autre application intressante de la commande début est l&#39;excution parallle l&#39;aide du paramtre /b comme dans le script 51.

N.B.: la commande temps libre n&#39;est pas fournie en standard sur tous les systmes Windows. Si vous ne l&#39;avez pas, veuillez supprimer la commande temps libre du script, d-commenter les commandes écho, ping et supprimer le caractre d&#39;chappement dans la commande ping.

1.
2
3
4
5
6
7.
8
9
dix.
11

@écho de
si "%1"=="foo" goto SecondInstance
début /b %~nx0 foo


temps libre /t 10 /nobreak
pause
sortie /b
:SecondInstance
écho %1
sortie
start_b

IV-J. La commande setlocal▲

Cette commande permet de modifier partiellement les contextes en crant un contexte local. Les variables et leurs valeurs, dans ce nouveau contexte local, sont soumises aux rgles inhrentes la cration de contexte. L&#39;avantage de cette commande est que l&#39;on peut crer un contexte sans passer par un appel. Ce contexte local ne possde pas d&#39;adresse de retour ni de paramtres d&#39;appel. Seules les variables, et ventuellement les extensions de commande, sont affectes. Ainsi, toutes les variables cres ou modifies dans ce contexte local y sont propres. Cette modification prend fin lorsque l&#39;excution rencontre la commande endlocal. The command setlocal prend aussi les paramtres:

  • enabledelayedexpansion qui active l&#39;expansion retarde;
  • disabledelayedexpansion qui dsactive l&#39;expansion retarde;
  • enableextensions qui active les extensions de commande;
  • disableextensions qui dsactive les extensions de commande.

setlocal [enableextensions[enableextensions[enableextensions[enableextensions|disableextensions][enabledelayedexpansion[enabledelayedexpansion[enabledelayedexpansion[enabledelayedexpansion|disabledelayedexpansion]

IV-K. La commande endlocal▲

Cette commande termine le contexte local gnr par la commande setlocal correspondante. Plusieurs contextes locaux pouvant tre empils les uns au-dessus des autres, toutes les modifications apportes dans le contexte local qui se termine sont perdues, y compris les modifications apportes par les paramtres de la commande setlocal. The command endlocal ne prend aucun paramtre. Exemple pour setlocal et endlocal avec le script 52:

1.
2
3
4
5
6
7.
8

@écho de
setlocal
ensemble "X=foo"
écho %X%
endlocal
écho %X%
pause
sortie
setlocal_endlocal

IV-L. Mise en application des contextes▲

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46
47
48.
49
50
51.
52
53
54
55
56.
57
58
59
60.
61.
62
63.
64.
65.
66.
67.
68.
69
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99
100
101.
102.
103.
104
105
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.

@écho de

ensemble "ScriptName=%~nx0"
ensemble "NegNum=false"
ensemble /a "PrefixEnable=0"
ensemble /a "UpperPrefix=0"

setlocal

:ParseArgs
si "%~1"=="" goto Init
si /i "%~1"=="/?" goto Help
si /i "%~1"=="-?" goto Help
si /i "%~1"=="/h" goto Help
si /i "%~1"=="-h" goto Help
si /i "%~1"=="/Aidez-moi" goto Help
si /i "%~1"=="-help" goto Help
si /i "%~1"=="/hex" (
    ensemble "SInt32=%~2"
    ensemble /a "SInt32"
    si errorlevel 1 (
        décalage /1
        goto BadSyntax
)
    décalage /1
    décalage /1
    goto ParseArgs
)
si /i "%~1"=="/p" (
    ensemble /a "PrefixEnable=1"
    si %~1 EQU /P ensemble /a "UpperPrefix=1"
    décalage /1
    goto ParseArgs
)
:BadSyntax
echo.


net helpmsg 87
écho [[[[%~1 ]
echo.
si ne pas "%~0"==":BadSyntax" endlocal
sortie /b 1

:Init
si défini SInt32 goto Exec
:UnknowError
appel :BadSyntax /hex
appel :Help
endlocal
sortie /b 2

:Exec

si %SInt32% LSS 0 (
    ensemble "NegNum=true"
    ensemble /a "SInt32=~SInt32"
)


ensemble /a "Nibble0= SInt32 %% 16","HighOrder0= SInt32 / 16"
ensemble /a "Nibble1=HighOrder0 %% 16","HighOrder1=HighOrder0 / 16"
ensemble /a "Nibble2=HighOrder1 %% 16","HighOrder2=HighOrder1 / 16"
ensemble /a "Nibble3=HighOrder2 %% 16","HighOrder3=HighOrder2 / 16"
ensemble /a "Nibble4=HighOrder3 %% 16","HighOrder4=HighOrder3 / 16"
ensemble /a "Nibble5=HighOrder4 %% 16","HighOrder5=HighOrder4 / 16"
ensemble /a "Nibble6=HighOrder5 %% 16"
ensemble /a "Nibble7=HighOrder5 / 16"


si "%NegNum%"=="true" (
    ensemble /a "Nibble0=15  Nibble0"
    ensemble /a "Nibble1=15  Nibble1"
    ensemble /a "Nibble2=15  Nibble2"
    ensemble /a "Nibble3=15  Nibble3"
    ensemble /a "Nibble4=15  Nibble4"
    ensemble /a "Nibble5=15  Nibble5"
    ensemble /a "Nibble6=15  Nibble6"
    ensemble /a "Nibble7=15  Nibble7"
)

si %Nibble0% GTR 9 (
    si %Nibble0% EQU dix ensemble "Nibble0=A"
    si %Nibble0% EQU 11 ensemble "Nibble0=B"
    si %Nibble0% EQU 12 ensemble "Nibble0=C"
    si %Nibble0% EQU 13 ensemble "Nibble0=D"
    si %Nibble0% EQU 14 ensemble "Nibble0=E"
    si %Nibble0% EQU 15 ensemble "Nibble0=F"
)
si %Nibble1% GTR 9 (
    si %Nibble1% EQU dix ensemble "Nibble1=A"
    si %Nibble1% EQU 11 ensemble "Nibble1=B"
    si %Nibble1% EQU 12 ensemble "Nibble1=C"
    si %Nibble1% EQU 13 ensemble "Nibble1=D"
    si %Nibble1% EQU 14 ensemble "Nibble1=E"
    si %Nibble1% EQU 15 ensemble "Nibble1=F"
)
si %Nibble2% GTR 9 (
    si %Nibble2% EQU dix ensemble "Nibble2=A"
    si %Nibble2% EQU 11 ensemble "Nibble2=B"
    si %Nibble2% EQU 12 ensemble "Nibble2=C"
    si %Nibble2% EQU 13 ensemble "Nibble2=D"
    si %Nibble2% EQU 14 ensemble "Nibble2=E"
    si %Nibble2% EQU 15 ensemble "Nibble2=F"
)
si %Nibble3% GTR 9 (
    si %Nibble3% EQU dix ensemble "Nibble3=A"
    si %Nibble3% EQU 11 ensemble "Nibble3=B"
    si %Nibble3% EQU 12 ensemble "Nibble3=C"
    si %Nibble3% EQU 13 ensemble "Nibble3=D"
    si %Nibble3% EQU 14 ensemble "Nibble3=E"
    si %Nibble3% EQU 15 ensemble "Nibble3=F"
)
si %Nibble4% GTR 9 (
    si %Nibble4% EQU dix ensemble "Nibble4=A"
    si %Nibble4% EQU 11 ensemble "Nibble4=B"
    si %Nibble4% EQU 12 ensemble "Nibble4=C"
    si %Nibble4% EQU 13 ensemble "Nibble4=D"
    si %Nibble4% EQU 14 ensemble "Nibble4=E"
    si %Nibble4% EQU 15 ensemble "Nibble4=F"
)
si %Nibble5% GTR 9 (
    si %Nibble5% EQU dix ensemble "Nibble5=A"
    si %Nibble5% EQU 11 ensemble "Nibble5=B"
    si %Nibble5% EQU 12 ensemble "Nibble5=C"
    si %Nibble5% EQU 13 ensemble "Nibble5=D"
    si %Nibble5% EQU 14 ensemble "Nibble5=E"
    si %Nibble5% EQU 15 ensemble "Nibble5=F"
)
si %Nibble6% GTR 9 (
    si %Nibble6% EQU dix ensemble "Nibble6=A"
    si %Nibble6% EQU 11 ensemble "Nibble6=B"
    si %Nibble6% EQU 12 ensemble "Nibble6=C"
    si %Nibble6% EQU 13 ensemble "Nibble6=D"
    si %Nibble6% EQU 14 ensemble "Nibble6=E"
    si %Nibble6% EQU 15 ensemble "Nibble6=F"
)
si %Nibble7% GTR 9 (
    si %Nibble7% EQU dix ensemble "Nibble7=A"
    si %Nibble7% EQU 11 ensemble "Nibble7=B"
    si %Nibble7% EQU 12 ensemble "Nibble7=C"
    si %Nibble7% EQU 13 ensemble "Nibble7=D"
    si %Nibble7% EQU 14 ensemble "Nibble7=E"
    si %Nibble7% EQU 15 ensemble "Nibble7=F"
)

ensemble "LSW=%Nibble3%%Nibble2%%Nibble1%%Nibble0%"

ensemble "MSW=%Nibble7%%Nibble6%%Nibble5%%Nibble4%"

si %PrefixEnable% EQU 1 (
    si %UpperPrefix% EQU 1 (
        écho 0X%MSW%%LSW%
    ) autre (
        écho 0x%MSW%%LSW%
    )
) autre (
    écho %MSW%%LSW%
)
goto End


:Help
echo.
écho %ScriptName% [/p^[/p^[/p^[/p^|/P]/hex ^<number^>
écho %ScriptName% -?^
echo.
écho     /hex    Dfinit le ^<number^> qui doit tre exprim en hexadcimal.
écho     /p      Dfinit que le prfixe doit tre affich en minuscules.
écho     /P      Dfinit que le prfixe doit tre affich en majuscules.
echo.    /?      Affiche cette aide.
echo.

:End
si ne pas "%~0"==":Help" endlocal
sortie /b 0

Le script 53 doit tre appel avec des paramtres afin de fonctionner. Ainsi, quand on appelle ce script avec l&#39;un des paramtres suivants: /?, , /h, -h, /help ou -help, l&#39;aide est affiche. Si on appelle le script avec les paramtres /hex n (ou n est le nombre voulu), il affiche la reprsentation hexadcimale de ce nombre. Notez galement l&#39;utilisation du paramtre %~nx0 pour dfinir le nom du script, ici, la fonction :Help est appele via un appel au label :UnknowError (la commande exit /b 0 du label :End fournit le saut l&#39;adresse de retour), %0 aurait t, alors, la chane :Help.

Un script devrait toujours avoir un squelette similaire celui du script 53. Pour en connatre la raison, examinons ses diffrentes parties:

  • le script commence par @Écho off pour rendre plus net l&#39;affichage, puis les variables de configuration sont initialises avec leurs valeurs par dfaut, ce qui permet au script de fonctionner mme si ces valeurs ne sont pas modifies par la suite. The command setlocal est utilise pour les cas d&#39;erreur, par exemple si le nombre donn via l&#39;argument /hex dpasse 32 bits. La variable ErrorLevel n&#39;est pas remise jour suite une erreur dans une commande interne, ainsi, si l&#39;on appelle le script depuis l&#39;interprteur avec en paramtre un nombre invalide, tous les appels du script qui suivront, mme avec un nombre valide, se termineront sur une erreur. Pensez utiliser la commande endlocal avant chaque point de sortie du script;
  • vient ensuite le label :ParseArgs dans lequel les paramtres d&#39;appel vont tre vrifis, chaque fois qu&#39;un paramtre est trouv, sa valeur est dfinie dans la variable correspondante puis les paramtres d&#39;appel sont dcals avant le retour au label :ParseArgs. Si le paramtre fourni dans la commande d&#39;appel n&#39;est pas trouv, l&#39;excution continue jusqu&#39;au label :BadSyntax qui affiche un message d&#39;erreur et quitte le script avec le code d&#39;erreur 1;
  • une fois tous les paramtres lus, l&#39;excution est redirige vers le label :Init, qui a pour fonction de vrifier que les donnes de travail ont bien t fournies dans la commande d&#39;appel. En effet, ce script appel sans paramtre s&#39;excute au moins jusqu&#39;au label :Init. Dans ce label, il convient, en gnral, de modifier les variables de configuration en fonction des valeurs fournies dans la commande d&#39;appel. Si les donnes fournies ne sont pas valides, l&#39;excution continue au label :UnknowError qui, dans notre cas, va afficher o se trouve l&#39;erreur ainsi que l&#39;aide;
  • si les donnes de travail sont valides, l&#39;excution est redirige vers le label :Exec qui va excuter le travail requis puis afficher le rsultat avant d&#39;tre redirige vers le label :End;
  • l'étiquette :Help fournit une aide en ligne de commande (c&#39;est toujours utile). Celui-ci se trouvant juste devant le label :End, il peut la fois tre utilis comme une fonction ou comme une portion de code classique. Notez l&#39;chappement de la commande écho avec le point la ligne echo. /? Affiche cette aide. sans quoi l&#39;interprteur aurait affich l&#39;aide de la commande écho.

Les boucles sont gres par la commande pour, elle permettent une grande quantit d&#39;actions sur des fichiers, des rpertoires ou des chanes de caractres. La boucle pour se compose d&#39;un ensemble sur lequel s&#39;opre une commande. le est pars puis transite au moyen d&#39;une autour du . La syntaxe de base de la boucle pour est la suivante.

pour %<variable> dans (<ensemble>) faire <ordre>

le est en fait un paramtre de commande propre la boucle pour. Elle utilise donc la syntaxe et les modificateurs de paramtre de commande (voir section IV.E.1Les modificateurs de paramtres de commande pour plus d&#39;information), ceci prs que le paramtre est dsign par une lettre et que le caractre % du paramtre doit tre chapp lorsque la boucle est utilise dans un script. Ainsi dans un script, le paramtre %A doit tre utilis avec le caractre d&#39;chappement %, ce qui nous donne la syntaxe %%A. Il faut aussi noter que les paramtres de la boucle pour respectent la casse, ainsi %a est diffrent de %A.

le est compos d&#39;une ou plusieurs entres. Si plusieurs entres sont prsentes, elles doivent tre spares par des virgules pour permettre la boucle de les distinguer correctement. Ce peut tre:

  • soit des noms de fichiers (avec leurs chemins d&#39;accs s&#39;ils ne sont pas dans le rpertoire courant);
  • soit des chemins d&#39;accs;
  • soit des chanes de caractres.

Toutes les composantes de l&#39; sont passes la sous forme de chanes de caractres. Seule l&#39;utilisation qui en est faite dans le traitement dtermine s&#39;il s&#39;agit d&#39;une chane de caractres, d&#39;un nom de fichier ou d&#39;un chemin d&#39;accs. Si une chane de l&#39; contient un ou plusieurs espaces, elle doit tre place entre guillemets. Exemple avec le script 54:

1.
2
3
4
5

@écho de
pour %%A dans (texte) faire écho %%A
pour %%B dans ("%cd%") faire si exister %%B écho %%B
pause
sortie /b
Pour

Si les extensions de commande sont actives, la boucle pour peut prendre un des paramtres de la liste suivante:

V-A. Les boucles pour chemin d&#39;accs▲

Les boucles pour chemin d&#39;accs permettent d&#39;effectuer des recherches de dossiers ou de fichiers. La recherche de dossier s&#39;effectue avec le paramtre /d tandis que la recherche de fichier s&#39;effectue avec le paramtre /r. Leurs syntaxes sont les suivantes:

pour /d %<paramtre> dans ([« ][[[[<chemin_d&#39;accs>]*["]) faire <cmd>

pour /r ["][[[[<chemin_d&#39;accs>]["] %<paramtre> dans (["]*["]) faire <cmd>

Options

Descriptions

Chemin d&#39;accs de base de la recherche. Si aucun chemin n&#39;est fourni dans la boucle, alors la recherche se porte sur le rpertoire courant.

*

Caractre gnrique. Remplace plusieurs caractres.

?

Caractre gnrique. Remplace un seul caractre.

Le motif dfinit le nom du fichier qu&#39;il faut chercher, il peut tre compos de tout caractre, y compris les caractres gnriques.

.

Avec le paramtre /r, le point, s&#39;il est utilis seul, signifie que la recherche porte sur les noms de dossier.

Tableau 12: Paramtres des boucles pour chemins d&#39;accs

Exemple avec le script 55.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21

@écho de
mkdir "%cd%foo"
mkdir "%cd%foobar"
mkdir "%cd%foobeer"
appel :WriteFile >>"%cd%foobarbar.bat"
appel :WriteFile >>"%cd%foobarbar.txt"
appel :WriteFile >>"%cd%foobeerbeer.bat"
appel :WriteFile >>"%cd%foobeerbeer.txt"
écho Liste des dossiers:
pour /d %%A dans ("%cd%foo*") faire écho %%A
echo.
écho Liste des scripts batch:
pour /r "%cd%foo" %%B dans ("*.bat") faire écho %%~B
echo.
pause
rd /s /q "%cd%foo"
sortie /b
:WriteFile
écho @écho de
écho pause
goto :eof
For_d_r

V-B. Les boucles pour compteurs▲

Le paramtre /l permet d&#39;effectuer une boucle avec comme paramtre un compteur numrique, ainsi l&#39; prend la forme: , , . La boucle commencera le traitement avec comme paramtre un nombre ayant pour valeur puis, aprs chaque itration de la boucle, sera ajout aussi longtemps que n&#39;est pas atteinte. Quand est atteinte la boucle excute sa dernire itration. , et peuvent tre spars, soit par des espaces, soit par des virgules.

pour /l %<paramtre> dans (<origine> <pas_incrmentiel> <fin>) faire <cmd>

pour /l %<paramtre> dans (<origine>,<pas_incrmentiel>,<fin>) faire <cmd>

1.
2
3
4

@écho de
pour /l %%A dans (1 1 20) faire écho Le paramtre A a pour valeur %%A.
pause
sortie /b
For_Counter

Comme les nombres dans l&#39;interprteur ont une dfinition de 32 bits et utilisent tous l&#39;arithmtique signe, les limites de la boucle for /l sont celles des nombres entiers signs. Ainsi l&#39;, la et le peuvent tous tre compris entre -2147483648 et +2147483647. Le script 57 fonctionne donc parfaitement, mais, comme vous pouvez l&#39;imaginer, son excution est trs longue.

1.
2
3
4

@écho de
pour /l %%A dans (2147483647 -1 -2147483648) faire écho Le paramtre A a pour valeur %%A.
pause
sortie /b

V-C. Les boucles de recherche▲

Le paramtre /f indique la boucle pour que le traitement peut s&#39;oprer sur des chanes de caractres, des fichiers ou des commandes, mais des fins de recherche. Ce paramtre a la particularit de prendre des options supplmentaires permettant de parser l&#39;.

pour /f["["["["<options>"]%<paramtre> dans (<ensemble>) faire <ordre>

Les options prises en charge par for /f sont les suivantes:

Options

Descriptions

eol=c

Dfinit le prfixe de commentaire, qui contrairement ce que suggre son nom (eol: End Of Line, ou fin de ligne) doit se trouver en dbut de ligne. Tout ce qui se trouve aprs le caractre spcifi sera ignor par la boucle pour. Il est recommand d&#39;utiliser le plus souvent possible le caractre ; pour la compatibilit avec les fichiers *.ini et *.inf (sous Windows), ou le caractre # si le script est susceptible de traiter des fichiers de type Unix.

skip=n

Nombre de lignes ignorer au dbut de l&#39;ensemble.

delims=xxx

Dlimiteurs, par dfaut: l&#39;espace et la tabulation. Cette option doit toujours tre donne en dernire position afin de pouvoir spcifier un retour la ligne comme dlimiteur. Cela se fait en crivant l&#39;option delims avec le symbole gal directement suivi du guillemet fermant du bloc d&#39;options.

tokens=x,y-z*

Spcifie l&#39;index des jetons devant tre transmis au corps de la boucle pour . Chaque jeton tant une chane se trouvant entre deux dlimiteurs dfinis par l&#39;option delims. La forme y-z dfinit une tendue allant des jetons y z. Si le dernier caractre de l&#39;option jetons est un astrisque (*), alors une variable supplmentaire est alloue et recevra tout le texte qui se trouve aprs le dernier jeton (y compris les dlimiteurs qui pourraient si trouver). Chaque jeton sera attribu un paramtre de la boucle pour en partant de celui spcifi dans la boucle et dans l&#39;ordre alphabtique. Si le paramtre %A est spcifi avec l&#39;option tokens=1-3*, alors le premier jeton sera accessible dans le corps de la boucle via le paramtre %A, le second via le paramtre %B, le troisime via le paramtre %C et enfin le reste de la ligne via le paramtre %D.

usebackq

Spcifie que la nouvelle smantique est en place, chaque chane se trouvant entre guillemets simples inverss (`) est excute en tant que commande et une chane entre guillemets simples (& # 39;) est une chane de caractres. La nouvelle smantique permet ainsi l&#39;utilisation de guillemets doubles (") pour citer des noms de fichiers ou pour utiliser une chane qui contient des guillemets doubles (").

Tableau 13: Paramtres de la boucle for /f

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

@écho de
setlocal enabledelayedexpansion

1>"%cd%test.txt" écho Ligne 1
1>>"%cd%test.txt" écho Ligne 2
1>>"%cd%test.txt" écho Ligne 3
1>>"%cd%test.txt" écho Ligne 4
1>>"%cd%test.txt" écho Ligne 5
1>>"%cd%test.txt" écho ;un petit commentaire

pour /f "eol=; delims=" %%A dans (&#39;type test.txt&#39;) faire écho %%A
echo.
pour /f "eol=; sauter=4 delims=" %%A dans (&#39;type test.txt&#39;) faire écho %%A
del /Q test.txt
echo.
pour /f "tokens=1-5*" %%A dans ("1 2 3 4 5 6 7 8 9") faire (
    écho %%A
    écho %%B
    écho %%C
    écho %%D
    écho %%E
    écho %%F
)
echo.
pour /f "usebackq delims=" %%A dans (`type "%cd%%~nx0"`) faire (
    écho %%A
)
echo.
pause
sortie /b
For_Find

Plusieurs points sont noter dans le script 58:

  • le premier est l&#39;utilisation de l&#39;option eol=; qui supprime la chane ;un petit commentaire des rsultats obtenus des deux premires boucles;
  • le second est l&#39;utilisation de l&#39;option skip=4 qui supprime les quatre premires lignes du rsultat de la seconde boucle;
  • le troisime est l&#39;absence de l&#39;option delims dans la troisime boucle, en effet l&#39;espace et la tabulation sont les dlimiteurs par dfaut;
  • le dernier est l&#39;utilisation de l&#39;option usebackq et des caractres ` (guillemet simple invers) qui permet l&#39;utilisation de guillemets doubles pour le chemin d&#39;accs.

V-D. Les chappements propres la boucle for▲

La boucle pour possde un certain nombre de caractres significatifs tel que " &#39; ` ,. Si les guillemets et autres apostrophes peuvent tre grs avec un bon jeu d&#39;options dans la boucle, il n&#39;en est pas de mme avec la virgule. Ainsi, considrons le script suivant qui devrait permettre de trouver les volumes qui sont des lecteurs de CD/DVD.

1.
2
3
4
5
6

@écho de
pour /f "usebackq skip=1 tokens=1,2" %%A dans (`wmic le volume  "DriveType="5"" get DriveLetter,Capacity`) faire (
    écho %%A %%B
)
pause
sortie /b 0

Ce script se finit sur une erreur, car les guillemets simples inverss modifient la faon dont la chane de l&#39;ensemble est prise en compte et de ce fait, la virgule provoque l&#39;erreur. Il faut donc chapper la virgule avec le caractre ^ pour qu&#39;elle soit incluse dans la chane sans tre traite par la boucle comme le montre le script 60.

1.
2
3
4
5
6

@écho de
pour /f "usebackq skip=1 tokens=1,2" %%A dans (`wmic le volume  "DriveType="5"" get DriveLetter^,Capacity`) faire (
    écho %%A %%B
)
pause
sortie /b 0

le, qu&#39;il soit une commande ou autre chose, est toujours trait dans un premier temps comme une chane. Ainsi les oprateurs de redirection (voir chapitre VIILa gestion des flux) doivent aussi tre chapps.

1.
2
3
4
5
6
7.
8
9
dix.

@écho de
1>test.txt écho foo
1>>test.txt écho bar
1>>test.txt écho foobar
pour /f "usebackq delims=" %%A dans (`type test.txt ^| trouver "foo"`) faire (
    écho %%A
)
del /q test.txt
pause
sortie /b 0

V-E. Mise en application des boucles▲

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46
47
48.
49
50
51.
52
53
54
55
56.
57
58
59
60.
61.
62
63.
64.
65.
66.
67.
68.
69
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99
100
101.
102.
103.
104
105
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.

@écho de

ensemble "ScriptName=%~nx0"
ensemble "NegNum=false"
ensemble /a "PrefixEnable=0"
ensemble /a "UpperPrefix=0"

setlocal

:ParseArgs
si "%~1"=="" goto Init
si /i "%~1"=="/?" goto Help
si /i "%~1"=="-?" goto Help
si /i "%~1"=="/h" goto Help
si /i "%~1"=="-h" goto Help
si /i "%~1"=="/Aidez-moi" goto Help
si /i "%~1"=="-help" goto Help
si /i "%~1"=="/hex" (
    ensemble "Nibble7=%~2"
    ensemble /a "Nibble7"
    si errorlevel 1 (
        décalage /1
        goto BadSyntax
)
    décalage /1
    décalage /1
    goto ParseArgs
)
si /i "%~1"=="/p" (
    ensemble /a "PrefixEnable=1"
    si %~1 EQU /P ensemble /a "UpperPrefix=1"
    décalage /1
    goto ParseArgs
)
:BadSyntax
echo.
pour /f "delims=" %%A dans (&#39;net helpmsg 87&#39;) faire écho [[[[%~1 ] %%A
echo.
si ne pas "%~0"==":BadSyntax" endlocal
sortie /b 1

:Init
si défini Nibble7 goto Exec
:UnknowError
appel :BadSyntax /hex
appel :Help
endlocal
sortie /b 2

:Exec

si %Nibble7% LSS 0 (
    ensemble /a "Nibble7=~Nibble7"
    ensemble "NegNum=true"
)

pour /l %%A dans (0 1 6) faire ensemble /a "Nibble%%A=Nibble7 %% 16", "Nibble7/=16"

si /i "%NegNum%"=="true" pour /l %%A dans (0 1 7) faire ensemble /a "Nibble%%A=15 - Nibble%%A"

si %Nibble0% GTR 9 (
    si %Nibble0% EQU dix ensemble "Nibble0=A"
    si %Nibble0% EQU 11 ensemble "Nibble0=B"
    si %Nibble0% EQU 12 ensemble "Nibble0=C"
    si %Nibble0% EQU 13 ensemble "Nibble0=D"
    si %Nibble0% EQU 14 ensemble "Nibble0=E"
    si %Nibble0% EQU 15 ensemble "Nibble0=F"
)
si %Nibble1% GTR 9 (
    si %Nibble1% EQU dix ensemble "Nibble1=A"
    si %Nibble1% EQU 11 ensemble "Nibble1=B"
    si %Nibble1% EQU 12 ensemble "Nibble1=C"
    si %Nibble1% EQU 13 ensemble "Nibble1=D"
    si %Nibble1% EQU 14 ensemble "Nibble1=E"
    si %Nibble1% EQU 15 ensemble "Nibble1=F"
)
si %Nibble2% GTR 9 (
    si %Nibble2% EQU dix ensemble "Nibble2=A"
    si %Nibble2% EQU 11 ensemble "Nibble2=B"
    si %Nibble2% EQU 12 ensemble "Nibble2=C"
    si %Nibble2% EQU 13 ensemble "Nibble2=D"
    si %Nibble2% EQU 14 ensemble "Nibble2=E"
    si %Nibble2% EQU 15 ensemble "Nibble2=F"
)
si %Nibble3% GTR 9 (
    si %Nibble3% EQU dix ensemble "Nibble3=A"
    si %Nibble3% EQU 11 ensemble "Nibble3=B"
    si %Nibble3% EQU 12 ensemble "Nibble3=C"
    si %Nibble3% EQU 13 ensemble "Nibble3=D"
    si %Nibble3% EQU 14 ensemble "Nibble3=E"
    si %Nibble3% EQU 15 ensemble "Nibble3=F"
)
si %Nibble4% GTR 9 (
    si %Nibble4% EQU dix ensemble "Nibble4=A"
    si %Nibble4% EQU 11 ensemble "Nibble4=B"
    si %Nibble4% EQU 12 ensemble "Nibble4=C"
    si %Nibble4% EQU 13 ensemble "Nibble4=D"
    si %Nibble4% EQU 14 ensemble "Nibble4=E"
    si %Nibble4% EQU 15 ensemble "Nibble4=F"
)
si %Nibble5% GTR 9 (
    si %Nibble5% EQU dix ensemble "Nibble5=A"
    si %Nibble5% EQU 11 ensemble "Nibble5=B"
    si %Nibble5% EQU 12 ensemble "Nibble5=C"
    si %Nibble5% EQU 13 ensemble "Nibble5=D"
    si %Nibble5% EQU 14 ensemble "Nibble5=E"
    si %Nibble5% EQU 15 ensemble "Nibble5=F"
)
si %Nibble6% GTR 9 (
    si %Nibble6% EQU dix ensemble "Nibble6=A"
    si %Nibble6% EQU 11 ensemble "Nibble6=B"
    si %Nibble6% EQU 12 ensemble "Nibble6=C"
    si %Nibble6% EQU 13 ensemble "Nibble6=D"
    si %Nibble6% EQU 14 ensemble "Nibble6=E"
    si %Nibble6% EQU 15 ensemble "Nibble6=F"
)
si %Nibble7% GTR 9 (
    si %Nibble7% EQU dix ensemble "Nibble7=A"
    si %Nibble7% EQU 11 ensemble "Nibble7=B"
    si %Nibble7% EQU 12 ensemble "Nibble7=C"
    si %Nibble7% EQU 13 ensemble "Nibble7=D"
    si %Nibble7% EQU 14 ensemble "Nibble7=E"
    si %Nibble7% EQU 15 ensemble "Nibble7=F"
)
si %PrefixEnable% EQU 1 (
    si %UpperPrefix% EQU 1 (
        écho 0X%Nibble7%%Nibble6%%Nibble5%%Nibble4%%Nibble3%%Nibble2%%Nibble1%%Nibble0%
    ) autre (
        écho 0x%Nibble7%%Nibble6%%Nibble5%%Nibble4%%Nibble3%%Nibble2%%Nibble1%%Nibble0%
    )
) autre (
    écho %Nibble7%%Nibble6%%Nibble5%%Nibble4%%Nibble3%%Nibble2%%Nibble1%%Nibble0%
)
goto End


:Help
echo.
écho %ScriptName% [/p^[/p^[/p^[/p^|/P]/hex ^<number^>
écho %ScriptName% -?^
echo.
écho     /hex    Dfinit le ^<number^> qui doit tre exprim en hexadcimal.
écho     /p      Dfinit que le prfixe doit tre affich en minuscules.
écho     /P      Dfinit que le prfixe doit tre affich en majuscules.
echo.    /?      Affiche cette aide.
echo.

:End
si ne pas "%~0"==":Help" endlocal
sortie /b 0

Comme vous pouvez le constater, le script a vu sa taille rduite, les plus malins auront srement compris que la transformation en reprsentation hexadcimale peut se faire via une boucle, mais nous verrons cela au prochain chapitre. Les boucles auront, quand mme, permis de condenser les oprations rptitives. La variable SInt32 a t remplace par Nibble7 afin de traiter les divisions successives via une boucle pour sans avoir rajouter une ligne pour traiter le dernier quartet. Le script 62 peut facilement tre utilis dans un autre script grce la boucle for /f, comme avec le script 63 (remplacer par le nom donn au script 62).

1.
2
3
4
5
6

@écho de
pour /f "delims=" %%A dans (&#39;<scriptname> /p /hex -1&#39;) faire ensemble "Result=%%A"
écho Rsultat:    %Result%
echo.
pause 
sortie /b
For_Call_Script

Dans le script 63, l&#39;option "delims=" est utilise pour rcuprer la sortie de la commande echo 0x%Nibble7%%Nibble6%… du script 62, car toutes les commandes écho se finissent par un retour la ligne, le dlimiteur doit donc tre un retour la ligne. Si plusieurs lignes doivent tre rcupres en sortie d&#39;un script, il est possible d&#39;ajouter un compteur de ligne, comme dans le script 64.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20

@écho de
setlocal enabledelayedexpansion



1>"%cd%test.bat" écho @écho de
1>>"%cd%test.bat" écho écho Ligne 1
1>>"%cd%test.bat" écho écho Ligne 2
1>>"%cd%test.bat" écho écho Ligne 3
ensemble /a "Counter=1"
pour /f "delims=" %%A dans (&#39;test.bat&#39;) faire (
    ensemble "Result!Counter!=%%A"
    ensemble /a "Counter+=1"
)
del /Q test.bat
pour /l %%B dans (1 1 !Counter!) faire (
    si ne pas "!Result%%B!"=="" écho Rsultat %%B:    !Result%%B!
)
pause 
sortie /b
For_Call_Script_Multiline

Par dfaut, l&#39;expansion retarde des variables n&#39;est pas active, cependant il est possible de modifier ce comportement grce deux cls de registre contenant des valeurs REG_DWORD, 0x1 si l&#39;expansion retarde est active et 0x0 si l&#39;expansion retarde est dsactive. Les entres spcifies dans la cl de l&#39;utilisateur prennent le pas sur les entres spcifies dans la cl machine. Si l&#39;expansion retarde est active ou dsactive via les paramtres /v:on ou /v:off of the order cmd, alors cette nouvelle configuration prend le pas sur la configuration du registre. Si par la suite, la commande setlocal est utilise pour activer ou dsactiver l&#39;expansion retarde, alors les paramtres de la commande setlocal ont priorit sur les paramtres /v:on et /v:off.

Cls registres relatives l&#39;expansion retarde des variables

Sélectionnez

HKEY_LOCAL_MACHINESoftwareMicrosoftCommand ProcessorDelayedExpansion
HKEY_CURRENT_USERSoftwareMicrosoftCommand ProcessorDelayedExpansion

Les variables ont une porte limite au contexte dans lequel elles sont dfinies. Pour pouvoir utiliser des variables dfinies dans un contexte descendant, il faut utiliser l&#39;expansion retarde. Celle-ci peut-tre active soit par dfaut si les cls de registre appropries ont t modifies dans ce sens, ou alors avec la commande setlocal enabledelayedexpansion. Une fois que l&#39;expansion retarde est active, chaque variable dfinie sera accessible aussi bien dans la pile que dans le tas.

Ainsi, lorsque vous expanserez une variable dans un contexte ascendant, la variable prendra la dernire valeur qui lui a t attribue comme spcifi au chapitre IVLa porte des variables: si l&#39;expansion retarde est active, chaque cration ou modification d&#39;une variable, sa valeur est copie la fois dans le tas et sur la pile. L&#39;expansion de ces variables se fait en utilisant le caractre ! (au lieu du caractre %) afin d&#39;indiquer l&#39;interprteur leurs emplacements.

Toutes les variables ayant t dclares avant l&#39;activation de l&#39;expansion retarde ne sont accessibles que dans le contexte qui leur est propre ou dans un contexte descendant du contexte de cration/modification.

VI-A. Cas de la boucle for▲

Dans une boucle pour, la dernire excution du corps de pour est fixe dans le contexte d&#39;appel de la boucle. Ainsi, dans le script 65, seule la dernire valeur est ajoute la variable Var.

1.
2
3
4
5
6
7.

@écho de
pour %%A dans (a,z) faire (
    ensemble "Var=%Var% %%A"
)
écho %Var%
pause
sortie /b 0
Expansion_For_0

Si l&#39;on modifie le script 65 en ajoutant l&#39;expansion retarde, l&#39;opration s&#39;effectue sans erreur (script 66).

1.
2
3
4
5
6
7.
8

@écho de
setlocal enabledelayedexpansion
pour %%A dans (a,z) faire (
    ensemble "Var=!Var! %%A"
)
écho %Var%
pause
sortie /b 0
Expansion_For_1

VI-B. Gnrer dynamiquement des noms de variables▲

Une autre application intressante de l&#39;expansion retarde des variables est de pouvoir crer des noms de variables en fonction de paramtres tel qu&#39;un index numrique ou une chane de caractres. Des noms de variables ainsi construits permettent de crer une abstraction de tableau qu&#39;il sera par la suite possible de parcourir rapidement avec une boucle pour. Du fait de la syntaxe des paramtres de la boucle pour, si l&#39;on venait placer le paramtre variable (l&#39;index numrique ou la chane de caractres) entre des caractres %, le parsage de la ligne de commande gnrerait forcment une erreur. Par exemple avec un paramtre %%A ayant une valeur de 1, si l&#39;on veut obtenir la variable ayant le nom Index1, il faudrait l&#39;crire %Index%%A%, mais l&#39;interprteur comprendrait qu&#39;il y a une variable %Index% et une variable %A%. Si, avec le mme exemple, on utilise l&#39;expansion retarde, la variable s&#39;crirait !Index%%A!, ainsi plus d&#39;erreur de parsage possible.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14

@écho de
setlocal enabledelayedexpansion
1>>test.txt écho Ligne1
1>>test.txt écho Ligne2
1>>test.txt écho Ligne3
ensemble /a "Counter=1"
pour /f "delims=" %%A dans (&#39;type test.txt&#39;) faire (
    ensemble "Var!Counter!=%%A"
    ensemble /a "Counter+=1"
)
del /Q test.txt
pour /l %%B dans (1 1 !Counter!) faire si ne pas "!Var%%B!"=="" écho !Var%%B!
pause
sortie /b 0
Expansion_Dynamic_Var

Afin de rendre plus intuitive la lecture du script, il est possible de prendre des habitudes syntaxiques pour reprsenter de telles abstractions de tableau. Les caractres qui viennent tout de suite l&#39;esprit sont srement les caractres [[[[ et ], ainsi une entre de tableau pourrait s&#39;crire NomTableau[i] ou je est l&#39;index numrique de position dans le tableau. Il suffit alors de parcourir le tableau index avec une boucle for /l ou de modifier directement la variable contenant la valeur l&#39;index voulu.

Les abstractions de tableaux littraux peuvent tre cres sur le mme principe, ainsi une entre de tableau serait accessible via l&#39;identifiant NomTableau[NomEntre]. Le parcours d&#39;un tel tableau peut se faire avec une boucle pour basique comme dans le script 68.

1.
2
3
4
5
6
7.
8
9
dix.
11

@écho de
setlocal enabledelayedexpansion

ensemble "Array[One]=Entre 1"
ensemble "Array[Two]=Entre 2"
ensemble "Array[Three]=Entre 3"

pour %%A dans (One,Two,Three) faire écho !Array[%%A]!

pause
sortie /b 0
Expansion_Literal_Array

Il faut savoir que l&#39;interprteur, par dfaut, n&#39;autorise que 8192 octets de donnes pour l&#39;ensemble des valeurs des variables, mais autorise 64Ko de donnes pour l&#39;ensemble des dfinitions de variables. Chaque dfinition de variable est compose du nom de la variable, du signe gal et de la valeur de la variable. Il reste donc 57344 octets (56Ko) pour placer les noms de variables et le signe gal, ce qui permet d&#39;utiliser les noms de variables comme valeur significative et de rcrer des structures de donnes ou des abstractions de tableaux.

VI-C. Parcourir une chane▲

L&#39;expansion retarde permet une quantit d&#39;actions sur les variables en modifiant l&#39;valuation syntaxique par l&#39;interprteur, la seule limite est la syntaxe. Par exemple, il est possible de vouloir connatre la taille d&#39;une chane de caractres lorsqu&#39;un script formate son affichage (ASCII Art, mini jeu en batch, etc.). Exemple avec le script 69.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

@écho de
setlocal enabledelayedexpansion
ensemble "X=xyz"
ensemble "Y="
écho X:
appel :strlen "%X%"
appel :impression "%X%" %ErrorLevel%
écho Y:
appel :strlen "%Y%"
appel :impression "%Y%" %ErrorLevel%
echo.
pause
sortie /b 0
:strlen
ensemble "str=%~1"
pour /l %%A dans (0 1 4096) faire (
    si "!str:~%%A,1!"=="" sortie /b %%A
)
sortie /b 0
:impression
si %~2 GEQ 1 (
    écho La chane &#39;%~1& # 39; a une taille de %~2 caractre^(s^).
) autre (
    écho La chane est vide.
)
goto :eof
Expansion_strlen

VI-D. Mise en application de l&#39;expansion retarde▲

Vous reconnaissez notre script tmoin, celui-ci a encore t modifi pour le rendre plus efficient. La transformation en notation hexadcimale reprend le concept de gnration dynamique de nom de variable. Dans le cas des divisions successives, l&#39;utilisation de l&#39;expansion retarde n&#39;est pas ncessaire, car la commande ensemble le gre automatiquement. De mme, lors de l&#39;expansion des variables NibbleX dans l'ordre écho, celles-ci n&#39;ayant jamais t dclares dans le contexte courant et l&#39;expansion retarde tant active depuis le dbut du script, elles sont donc implicitement adresses dans le tas. Nibble7 a t dclare dans le contexte du script, cependant c&#39;est toujours la dernire qui est traite dans les boucles, donc ses valeurs successives sont toujours fixes dans le contexte du script.

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46
47
48.
49
50
51.
52
53
54
55
56.
57
58
59
60.
61.
62
63.
64.
65.
66.
67.
68.
69
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.

@écho de

ensemble "ScriptName=%~nx0"
ensemble "NegNum=false"
ensemble /a "PrefixEnable=0"
ensemble /a "UpperPrefix=0"


setlocal
setlocal enabledelayedexpansion

:ParseArgs
si "%~1"=="" goto Init
si /i "%~1"=="/?" goto Help
si /i "%~1"=="-?" goto Help
si /i "%~1"=="/h" goto Help
si /i "%~1"=="-h" goto Help
si /i "%~1"=="/Aidez-moi" goto Help
si /i "%~1"=="-help" goto Help
si /i "%~1"=="/hex" (
    ensemble "Nibble7=%~2"
    ensemble /a "Nibble7"
    si errorlevel 1 (
        décalage /1
        goto BadSyntax
)
    décalage /1
    décalage /1
    goto ParseArgs
)
si /i "%~1"=="/p" (
    ensemble /a "PrefixEnable=1"
    si %~1 EQU /P ensemble /a "UpperPrefix=1"
    décalage /1
    goto ParseArgs
)
:BadSyntax
echo.
pour /f "delims=" %%A dans (&#39;net helpmsg 87&#39;) faire écho [[[[%~1 ] %%A
echo.
si ne pas "%~0"==":BadSyntax" endlocal
sortie /b 1

:Init
si défini Nibble7 goto Exec
:UnknowError
appel :BadSyntax /hex
appel :Help
endlocal
sortie /b 2

:Exec

si %Nibble7% LSS 0 (
    ensemble /a "Nibble7=~Nibble7"
    ensemble "NegNum=true"
)

pour /l %%A dans (0 1 6) faire ensemble /a "Nibble%%A=Nibble7 %% 16", "Nibble7/=16"

si /i "%NegNum%"=="true" pour /l %%A dans (0 1 7) faire ensemble /a "Nibble%%A=15 - Nibble%%A"

pour /l %%A dans (0 1 7) faire (
    si !Nibble%%A! EQU dix ensemble "Nibble%%A=A"
    si !Nibble%%A! EQU 11 ensemble "Nibble%%A=B"
    si !Nibble%%A! EQU 12 ensemble "Nibble%%A=C"
    si !Nibble%%A! EQU 13 ensemble "Nibble%%A=D"
    si !Nibble%%A! EQU 14 ensemble "Nibble%%A=E"
    si !Nibble%%A! EQU 15 ensemble "Nibble%%A=F"
)
si %PrefixEnable% EQU 1 (
    si %UpperPrefix% EQU 1 (
        écho 0X%Nibble7%%Nibble6%%Nibble5%%Nibble4%%Nibble3%%Nibble2%%Nibble1%%Nibble0%
    ) autre (
        écho 0x%Nibble7%%Nibble6%%Nibble5%%Nibble4%%Nibble3%%Nibble2%%Nibble1%%Nibble0%
    )
) autre (
    écho %Nibble7%%Nibble6%%Nibble5%%Nibble4%%Nibble3%%Nibble2%%Nibble1%%Nibble0%
)
goto End


:Help
echo.
écho %ScriptName% [/p^[/p^[/p^[/p^|/P]/hex ^<number^>
écho %ScriptName% /Aidez-moi^
echo.
écho     /hex    Dfinit le ^<number^> qui doit tre exprim en hexadcimal.
écho     /p      Dfinit que le prfixe doit tre affich en minuscules.
écho     /P      Dfinit que le prfixe doit tre affich en majuscules.
echo.    /?      Affiche cette aide.
echo.

:End
si ne pas "%~0"==":Help" endlocal
sortie /b 0

Depuis le dbut de ce document, nous avons utilis des flux de donnes sans le savoir. Dans le cas d&#39;un script batch, un flux de donnes est l&#39;ensemble des donnes textuelles qu&#39;une commande reoit pour son excution et qu&#39;elle produit pendant cette mme excution. Ce flux de donnes transite via le canal standard.

VII-A. Le canal standard▲

Lors de l&#39;excution d&#39;une commande, l&#39;interprteur alloue un espace de mmoire supplmentaire pour cette commande. Cet espace de mmoire est appel canal standard, il permet aux commandes excutes de recevoir des donnes et de renvoyer des messages d&#39;erreurs ou de russites. Le canal standard a une entre (aussi appele entre standard ou STDIN), une sortie (aussi appele sortie standard ou STDOUT) et une troisime partie rserve aux messages d&#39;erreurs (appels erreurs standards ou STDERR). Le flux de donnes arrive dans l&#39;entre standard, il est trait par la commande puis un message de rponse est envoy dans la sortie standard. Si une erreur survient pendant l&#39;excution de la commande, le message d&#39;erreur (s&#39;il y en a un) est plac dans l&#39;erreur standard. Par dfaut, ds qu&#39;une donne est place dans la sortie standard ou dans l&#39;erreur standard, elle est affiche par l&#39;interprteur. Chaque partie du canal standard est dsigne par un numro qui lui est propre, ce numro est appel handle. Il permet l&#39;interprteur d&#39;identifier la zone de mmoire rserve chaque partie du canal. Notez qu&#39;un handle dsigne un fichier charg en mmoire, l&#39;interprteur traite les constituants du canal standard comme des fichiers chargs en mmoire. Dans la suite de ce chapitre, nous utiliserons le terme tampon pour dsigner un fichier charg en mmoire afin de ne pas induire le lecteur en erreur. Le schma ci-dessous reprsente le droulement de l&#39;excution d&#39;une commande.

STD_Chanel

VII-B. Les oprateurs de redirection▲

Afin de pouvoir contrler les mouvements d&#39;un flux, l&#39;interprteur fournit les oprateurs de redirection qui permettent, par exemple, d&#39;envoyer des donnes dans un fichier ou de lire les donnes contenues dans un fichier. Le tableau ci-dessous donne une liste des diffrents oprateurs de redirection, leur syntaxe ainsi qu&#39;une courte description.

Oprateur

Syntaxe

La description

Et

Cmd1 & Cmd2

Cmd1 est excut puis, quel que soit son rsultat, Cmd2 est excut.

&&

Cmd1 && Cmd2

Cmd1 est excut, puis si et seulement si Cmd1 ne produit pas d&#39;erreur, Cmd2 est excut.

|

Cmd1 | Cmd2

Cmd1 est excut puis la sortie (STDOUT) de Cmd1 est envoye dans l&#39;entre (STDIN) de Cmd2.

||

Cmd1 || Cmd2

Cmd1 est excut puis, si et seulement si Cmd1 produit une erreur, Cmd2 est excut.

<

Cmd1 < File

Le contenu du fichier (File) est envoy dans l&#39;entre (STDIN) de Cmd1.

>

Cmd1 > File

Cmd1 est excut, sa sortie (STDOUT) est envoye dans un fichier(File). L&#39;opration s&#39;effectue en criture seule, le fichier de destination n&#39;est pas lu et cela a pour effet de le remplacer par un fichier ne contenant que les nouvelles donnes.

Handle>File

Le contenu du tampon dsign par l&#39;Handle est copi dans le fichier (File) de destination. L&#39;opration s&#39;effectue en criture seule, le fichier de destination n&#39;est pas lu et cela a pour effet de le remplacer par un fichier ne contenant que les nouvelles donnes.

>>

Cmd1 >> File

Cmd1 est excut, sa sortie (STDOUT) est envoye dans un fichier (File). L&#39;opration s&#39;effectue en lecture et criture, les donnes contenues dans le fichier de destination sont lues puis la sortie de Cmd1 est ajoute la fin.

Handle>>File

Le contenu du tampon dsign par l&#39;Handle est copi dans le fichier (File) de destination. L&#39;opration s&#39;effectue en lecture et criture, les donnes contenues dans le fichier de destination sont lues puis le contenu du tampon dsign par l&#39;Handle est ajout la fin.

<&

<& Handle

Redirige l&#39;entre standard (STDIN) dans le tampon dsign par l&#39;Handle.

Handle1 <& Handle2

Redirige le flux entrant dans le tampon dsign par l&#39;Handle1 dans le tampon dsign par l&#39;Handle2.

>&

>& Handle

Redirige la sortie standard (STDOUT) dans le tampon dsign par l&#39;Handle.

Handle1>& Handle2

Redirige le flux sortant du tampon dsign par l&#39;Handle1 dans le tampon dsign par l&#39;Handle2.

Tableau 14: Oprateurs de redirection

VII-C. L&#39;oprateur &▲

Cet oprateur permet d&#39;excuter plusieurs commandes, les unes la suite des autres, sans tenir compte de ce qui s&#39;est pass durant l&#39;excution de la commande prcdente. Ainsi, chaque fois que l&#39;interprteur rencontre l&#39;oprateur Et, il sait qu&#39;une autre commande est excuter, on parle d&#39;excution squentielle.

1.
2
3
4
5

@écho de Et cls
écho Affichage:
echo. Et echo. Et écho 1 Et écho 2
echo. Et  echo.
pause Et sortie /b 0
Operateur_AND

VII-D. La sortie standard▲

La sortie standard ( ne pas confondre avec l&#39;affichage standard que l&#39;on a vu au chapitre I) reoit les messages d&#39;une commande excute dans l&#39;interprteur. Le meilleur exemple d&#39;utilisation de la sortie standard est la commande écho qui ne fait qu&#39;envoyer les donnes qui lui sont passes en paramtres dans la sortie standard. Chaque fois qu&#39;une chane de caractres est envoye dans la sortie standard, l&#39;interprteur l&#39;affiche aussitt. Il est possible de rediriger la sortie standard vers un fichier ou dans l&#39;entre d&#39;une autre commande. Si la sortie standard est redirige, tout ce qui est envoy dans la sortie standard est ensuite plac dans sa nouvelle destination et rien n&#39;est affich dans l&#39;interprteur. La sortie standard peut-tre dsigne par son handle (1) ou de faon implicite si le caractre > est utilis dans l&#39;oprateur de redirection. Les redirections peuvent tre places avant ou aprs la commande, cela ne change rien leurs significations. Le schma ci-dessous reprsente l&#39;excution d&#39;une commande avec redirection de la sortie standard.

STD_Out

VII-E. Les oprateurs > et >>▲

Ces oprateurs permettent de rediriger la sortie standard ou le contenu d&#39;un tampon vers un fichier. Seul le mode d&#39;ouverture du fichier de destination diffre entre ces deux oprateurs. Ainsi, avec l&#39;oprateur >, le fichier de destination n&#39;est pas lu, les donnes sont donc effaces par l&#39;criture des nouvelles donnes. Avec l&#39;oprateur >>, le fichier de destination est lu puis les nouvelles donnes sont ajoutes la suite de celles dj contenues dans le fichier de destination. Dans le script 72, la chane foo n&#39;est pas dans le fichier Output.txt lorsqu&#39;il est affich par la commande type Output.txt, car le fichier n&#39;a pas t lu lors de l&#39;ajout de la chane bar.

1.
2
3
4
5
6
7.
8

@écho de
écho foo>Output.txt
écho bar>Output.txt
écho foobar>>Output.txt
type Output.txt
del /Q Output.txt
pause
sortie /b 0
Image non disponible" width="360" height="77

VII-F. L&#39;erreur standard▲

L&#39;erreur standard reoit les messages d&#39;erreurs d&#39;une commande, ces informations sont des chanes de caractres exposant, en langage humain, o se trouve l&#39;erreur. Par dfaut, l&#39;interprteur affiche les donnes contenues dans l&#39;erreur standard moins que le flux ne soit redirig vers un fichier. L&#39;handle de l&#39;erreur standard est le 2 et elle n&#39;est jamais utilise de faon implicite, elle doit donc toujours tre spcifie dans la redirection. Il faut aussi noter que certaines commandes permutent les handles 1 et 2, cela est d de mauvaises pratiques de programmation.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19

@écho de

2>Log.txt ensemble /a "Err=09"
écho La commande a t excute.
echo.
type Log.txt
del /Q Log.txt
echo.
echo.

changement port /? 2>>HelpChangePort.txt
écho Syntaxe de changement port:
echo.
type HelpChangePort.txt
del /Q HelpChangePort.txt
echo.
echo.
pause
sortie
STDERR

VII-G. L&#39;entre standard▲

L&#39;entre standard est tout ce que la commande reoit comme donnes, elle comprend la saisie au clavier de l&#39;utilisateur (s&#39;il y en a une) ainsi que le ou les fichiers qui seront envoys par ce biais. L&#39;handle de l&#39;entre standard est 0, mais elle peut aussi tre utilise de manire implicite si le caractre < est utilis dans l&#39;oprateur de redirection. Ci-dessous le schma de l&#39;excution d&#39;une commande avec redirection vers l&#39;entre standard.

Image non disponible" width="550" height="249

Exemple avec le script 74:

1.
2
3
4
5
6
7.
8

@écho de
1>>test.txt écho foo
1>>test.txt écho bar
1>>test.txt écho foobar
<test.txt plus
del /q test.txt
pause
sortie /b 0
Redirection_stdin

L&#39;entre standard ne peut tre redirige directement vers un fichier sur le disque dur, les donnes doivent d&#39;abord tre rediriges vers un tampon avant de pouvoir tre rediriges vers un fichier, c&#39;est d au fait que cela n&#39;a thoriquement pas de sens. Exemple avec le script 75:

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

@écho de
cls

1>test.txt écho     Ligne 1
1>>test.txt écho     Ligne 2

écho Redirection 1:
0>>LogInput.txt type test.txt
écho Output 1:
type LogInput.txt
del /Q LogInput.txt
echo.

écho Redirection 2:
0<Et3>>LogInput.txt type test.txt
écho Output 2:
type LogInput.txt
del /Q LogInput.txt
echo.

écho Redirection 3:
<Et3>logInput.txt type test.txt
écho Output 3: 
type LogInput.txt
del /Q LogInput.txt
echo.
del /Q test.txt
pause
sortie /b 0
Redirection_stdin_file

Comme vous pouvez le voir dans l&#39;affichage du script 75, lorsqu&#39;on redirige l&#39;entre standard directement depuis l&#39;handle 0 vers le fichier de sortie, rien ne se produit; en effet, il n&#39;est pas possible de rediriger l&#39;entre standard directement, il faut rediriger son contenu dans un autre tampon pour pouvoir le rediriger vers un fichier. Dans le deuxime et le troisime cas de notre exemple, l&#39;entre standard est redirige dans le tampon dsign par l&#39;handle 3 avant d&#39;tre redirige vers le fichier, la commande type test.txt ne sert ici qu&#39; charger le fichier dans l&#39;entre standard.

VII-H. Le pseudo-priphrique NUL▲

Un pseudo-priphrique dnomm NUL est galement disponible (si on le compare avec les systmes de type Unix, ce serait le priphrique NUL, accessible via le point de montage /dev/nul). Il renvoie les donnes nulle part , celles-ci seront simplement supprimes du tampon source et seront donc dfinitivement perdues. Ce pseudo-priphrique trouve son utilit dans un certain nombre de cas comme lorsqu&#39;on ne veut pas que la sortie d&#39;une commande apparaisse dans l&#39;affichage de l&#39;interprteur. Ce pseudo-priphrique n&#39;a pas d&#39;handle, mais un pseudo-fichier de priphrique afin d&#39;tre trait par l&#39;interprteur comme tant un fichier. Il n&#39;a pas d&#39;utilisation implicite et il ne devrait pas non plus tre utilis en entre puisqu&#39;il ne contient aucune donne. Il peut donc tre utilis en sortie de tous les autres tampons. Il est utilisable via le pseudo-fichier non, comme dans le script 76.

1.
2
3
4
5
6
7.
8

@écho de
écho test 1>non
ensemble /a "Var=09" 2>non
ensemble /p "Var2=Entrez une chane:    " 0>non
echo.
écho %Var2%
pause 
sortie
Redirection_NUL_0

Dans le script 76, la commande set /p "Var2=Entrez une chane: " 0>nul se termine avant que l&#39;utilisateur ne puisse entrer quoi que se soit, cela est d la redirection de l&#39;entre standard vers le pseudo-priphrique NUL. Ainsi lorsque Var2 est expanse, celle-ci est vide; ce qui provoque l&#39;affichage de la ligne Commande ECHO dsactive. Si l&#39;on retire la commande echo. du script 76, on obtient l&#39;affichage suivant:

Redirection_NUL_1

La chane d&#39;invite a bien t envoye dans la sortie standard, mais comme set /p attend des donnes en provenance de l&#39;entre standard et que celle-ci est renvoye vers le pseudo-priphrique NUL, le traitement de la commande est perdu et le retour la ligne ne se fait jamais. Cela s&#39;avre fort pratique lorsqu&#39;il est ncessaire d&#39;ajouter du texte dans un fichier sans retour la ligne.

Le pseudo-fichier NUL est rserv par le systme, il n&#39;est donc pas possible de crer un fichier portant ce nom (mme avec une extension de fichier).

VII-I. L&#39;oprateur |▲

Cet oprateur, appel Pipe, permet de rediriger la sortie d&#39;une commande dans l&#39;entre de la commande suivante, on parle de pipe-line de commande. Cependant, toutes les commandes n&#39;ont pas la capacit de traiter les donnes contenues dans l&#39;entre standard; les commandes qui peuvent faire cela sont appeles des filtres.

VII-I-1. Les filtres▲

Il existe plusieurs commandes qui agissent comme des filtres, c&#39;est--dire qu&#39;elles ont la capacit de rcuprer le contenu de l&#39;entre standard, d&#39;excuter leurs traitements en fonction du contenu de l&#39;entre standard puis d&#39;envoyer leurs messages de rsultat dans la sortie standard afin d&#39;tre rcuprs par un des diffrents moyens existants tels que les boucles pour ou les redirections. Voici une liste non exhaustive des commandes pouvant tre utilises comme filtres.

Ordres

Descriptions

trouver

Effectue une recherche de sous-chanes dans les chanes de l&#39;entre standard (chaque chane de l&#39;entre standard est spare par un ) puis renvoie les rsultats dans la sortie standard.

sort

Effectue un tri par ordre alphabtique dans les chanes de l&#39;entre standard (chaque chane de l&#39;entre standard est spare par un ) puis renvoie les rsultats dans la sortie standard.

plus

Rcupre l&#39;entre standard puis envoie les donnes par paquets de tailles quivalentes la taille de la fentre de l&#39;interprteur dans la sortie standard pour qu&#39;ils soient affichs.

findstr

Effectue une recherche de sous-chanes dans les chanes de l&#39;entre standard (chaque chane de l&#39;entre standard est spare par un ) puis renvoie les rsultats dans la sortie standard.

Tableau 15: Les filtres

N.B.: est un retour la ligne, format Windows, d&#39;une taille de deux octets.

Exemple avec le script 77.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18

@écho de
(écho foo Et écho bar Et écho foobar Et écho tester Et écho retest Et écho Oui Et écho no)>>test.txt
écho Affichage de sortie du filtre Sort:
type test.txt|sort
echo.
écho Affichage de sortie du filtre Find:
type test.txt|trouver "test"
echo.
écho Affichage de sortie du filtre Findstr:
type test.txt|findstr tester
echo.
pause
mode chatte cols=80 lines=5
type test.txt|plus
echo.
del /Q test.txt 
pause
sortie /b 0
Filtre_1
Filtre_2
Filtre_3

VII-I-2. Le filtre find▲

Find est une commande simple de recherche de chanes, mais elle n&#39;en est pas moins utile pour une recherche rapide et peu complexe de chanes. Elle prend plusieurs paramtres tels que /i qui rend la recherche insensible la casse, /n qui affiche les numros des lignes trouves, /c qui n&#39;affiche que le nombre de lignes trouves et /v qui ne recherche que les lignes ne contenant pas la chane.

Dans le script 78, le pipe doit tre chapp afin de ne pas provoquer d&#39;erreur. En effet, la transition de la commande du contexte du script vers celui de l&#39;ensemble se fait sous forme de chane de caractres, il faut donc traiter la commande comme telle.

1.
2
3
4
5
6
7.
8

@écho de
(écho Contenu de la ligne 1 Et écho Contenu de la ligne 2) 1>>text.txt
pour /f "usebackq delims=" %%A dans (`type text.txt^|trouver /n /v ""`) faire (
    pour /f "tokens=1-2 delims=[]" %%a dans ("%%A") faire écho Ligne %%a: %%b
)
del /Q text.txt
pause
sortie /b 0
Filtre_Find

VII-I-3. Le filtre sort▲

The command sort effectue un tri par ordre alphabtique entre les chanes qui lui sont passes en paramtres, ce qui permet de formater la sortie un peu comme un dictionnaire. Elle prend plusieurs paramtres tels que /r qui inverse l&#39;ordre de tri, /o qui dfinit un fichier de sortie pour le tri, /t qui dfinit un rpertoire temporaire pour l&#39;excution du tri, /l qui dfinit les paramtres rgionaux pour l&#39;excution du tri ou encore /+n qui indique partir de quel caractre commence le tri (ou n est l&#39;index du premier caractre en partant de 1).

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17

@écho de
1>text.txt  écho zxy0
1>>text.txt écho abc9
1>>text.txt écho 9abc
1>>text.txt écho 0zxy
écho Trie 1:
pour /f "delims=" %%a dans (&#39;type text.txt^|sort /r&#39;) faire (
    écho %%a
)
echo. Et écho Trie 2:
pour /f "delims=" %%a dans (&#39;type text.txt^|sort /+2&#39;) faire (
    écho %%a
)
del /Q text.txt
echo.
pause
sortie /b 0
Filtre_Sort

VII-I-4. Le filtre more▲

The command plus s&#39;utilise gnralement pour formater un affichage, mais elle peut aussi tre utilise dans le but de formater un lot de donnes dont le traitement ncessite une taille particulire ou de remplacer les tabulations par des espaces.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14

@écho de
1>test.txt écho Tab1:    "
1>>test.txt écho Tab2:        "
1>>test.txt écho Tab3:            "
écho le texte:
type test.txt
echo.
écho la sortie:
pour /f "delims=" %%A dans (&#39;type test.txt^|plus /T1&#39;) faire (
    écho %%A
)
del /Q test.txt
pause
sortie /b 0
Filtre_More

VII-I-5. Le filtre findstr▲

The command findstr permet des recherches de chanes, mais la diffrence de trouver, elle supporte des regexs. Mme si celles-ci sont plutt pauvres aux vues de celles dont disposent d&#39;autres langages tels que Perl ou des regexs POSIX, elles n&#39;en sont pas moins utiles pour traiter des chanes. Voici une liste des motifs qu&#39;elles supportent:

Modèle

La description

.

Caractre joker, correspond une occurrence de tout caractre quel qu&#39;il soit.

*

Rptition, zro occurrence ou plus du caractre ou de la classe le prcdent.

^

Motif de dbut de ligne.

$

Motif de fin de ligne.

x

Utilisation littrale du mtacaractre x.

<xyz

Motif de dbut de mot.

xyz>

Motif de fin de mot.

[classe]

Classe de caractres, correspond tout caractre compris dans la classe.

[^classe]

Classe inverse, correspond tout caractre non compris dans la classe.

[x-y]

Limites, correspond tout caractre dans les limites spcifies.

Tableau 16: Motifs des regexs de findstr

Vous aurez srement remarqu que certains de ces caractres sont significatifs pour l&#39;interprteur. En effet, les caractres ^<> doivent tre chapps pour pouvoir tre utiliss dans une regex de findstr, que a soit dans un script ou dans l&#39;interprteur. Ainsi pour trouver la chane , il est ncessaire d&#39;utiliser la regex suivante:

^^^$

Il faut distinguer deux types d&#39;chappement dans la regex prcdente: les chappements inhrents la ligne de commande et les chappements propres la regex. Ainsi, les chappements de la ligne de commande sont ceux exposs au chapitre ILes chappements de caractres, soit <>|^&%; et les chappements de la regex sont tous les mtacaractres d&#39;une regex, soit .*$[]-. Ces caractres propres la regex doivent tre chapps avec le caractre . Dans le cas des motifs de dbut et de fin de mot (<>), ces caractres doivent tre chapps avec le caractre pour signifier la regex qu&#39;ils sont des mtacaractres de la regex et non pas des caractres de la chane.

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46
47
48.
49
50
51.
52
53
54
55
56.
57
58
59
60.
61.
62
63.
64.
65.
66.
67.
68.
69
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.

@écho de
cls

(
  écho foo
  écho fao
  écho fa
  écho bar0
  écho bar1
  écho bar2
  écho bar3
  écho barfoo
  écho ^<?xml version="1.1" encoding="UTF-8" ?^>
  écho ^^*
  écho [MySection]
  écho C:WindowsSystem32cmd.exe
)>>SMS

écho Contenu du fichier:
type SMS
echo.
echo.

écho Dbut de chane(^^bar):
type SMS|findstr ^^bar
echo.

écho Fin de chane(1$):
type SMS|findstr 1$
echo.

écho Dbut de mot(^<fa):
type SMS|findstr ^<fa
echo.

écho Fin de mot(2^>):
type SMS|findstr 2^>
echo.

écho Caractre unique(^<f.^>):
type SMS|findstr ^<f.^>
echo.

écho Zro ou plus doccurrences du caractre o(^<fo*^>):
type SMS|findstr ^<fo*^>
echo.

écho Dans une classe de caractres(^<F[ao]o^>):
type SMS|findstr ^<F[ao]o^>
echo.

écho Zro ou plus d&#39;occurrences de la classe de caractres[ao](^<F[ao]*^>):
type SMS|findstr ^<F[ao]*^>
echo.

écho Intervalle de caractres dans une classe(^<bar[0-9]^>):
type SMS|findstr ^<bar[0-9]^>
echo.

écho Hors de la classe de caractres(^<bar[^^12]^>):
type SMS|findstr ^<bar[^^12]^>
echo.

écho Hors d&#39;un intervalle de caractres dans une classe(^<bar[^^1-9]^>):
type SMS|findstr ^<bar[^^1-9]^>
echo.

écho Zro ou plus d&#39;occurrences hors d&#39;un intervalle de caractres dans une classe(^<bar[^^0-9]*^>):
type SMS|findstr ^<bar[^^0-9]*^>
echo.

écho Dclaration XML ("^^^<?xml version="1.[0-1]*" encoding="[0-9a-z-]*" ?^>$"):
type SMS|findstr "^^^<?xml version="1.[0-1]*" encoding="[0-9a-z-]*" ?^>$"
echo.

écho Mtacaractre(^<[^^[^^[^^[^^*]*^>):
type SMS|findstr ^<[^^[^^[^^[^^*]*^>
echo.

écho Section *.ini(^<[[a-z]*]^>):
type SMS|findstr ^<[[a-z0-9]*]^>
echo.

écho Chemin d&#39;accs(^<[a-z:]*[a-z]*System32[a-z]*.[a-z]*^>):
type SMS|findstr /i ^<[a-z:]*[a-z]*System32[a-z]*.[a-z]*^>
echo.

del /Q txt
pause
sortie /b 0
Regex

VII-J. L&#39;oprateur <▲

Cet oprateur place le contenu d&#39;un fichier dans l&#39;entre standard pour l&#39;excution d&#39;une commande. Cette dernire doit tre un filtre pour pouvoir traiter les donnes contenues dans l&#39;entre standard.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17

@écho de
1>text.txt  écho foo
1>>text.txt écho bar
1>>text.txt écho foobar
écho Sort:
echo.
sort <text.txt
echo.
echo.
écho Findstr:
echo.
<text.txt findstr /i ^<foo
echo.
echo.
del /Q text.txt
pause
sortie /b 0
Operateur_stdin

VII-K. Le point sur set /p et type▲

set /p et type ne sont pas des filtres, mme s&#39;ils utilisent l&#39;entre standard, ils ne rcuprent pas son contenu. set /p utilise la sortie standard avant d&#39;attendre des donnes en provenance de l&#39;entre standard; cela a pour effet de supprimer toutes les donnes qui s&#39;y trouvent. Il est donc inutile de tenter de se servir de set /p ainsi, car cela ne fonctionnera jamais. In regards to type, le contenu du fichier afficher est plac dans l&#39;entre standard puis renvoy dans la sortie standard, toutes les donnes prsentes au moment du chargement du fichier dans l&#39;entre standard seront crases. Il n&#39;est donc pas plus possible de tenter ce genre de chose avec type.

VII-L. Les oprateurs && et ||▲

Ces oprateurs permettent de grer les erreurs dans un script. L&#39;oprateur && permet d&#39;excuter une commande seulement si la commande prcdente n&#39;a pas provoqu d&#39;erreur; ainsi la seconde commande ne s&#39;excute qu&#39;en cas de russite de la premire. Exemple avec le script 83:

1.
2
3
4
5
6
7.
8
9

@écho de
2>non ensemble "var=foo" EtEt 2>non ensemble "var2=bar"
ensemble var
echo.
2>non ensemble /a "nb=09" EtEt 2>non ensemble /a "nb2=07"
ensemble nb
echo.
pause
sortie /b
Operateur_ANDAND

L&#39;oprateur || n&#39;excute la commande qui le suit seulement si la commande qui le prcde provoque une erreur, ainsi la seconde commande ne s&#39;excute qu&#39;en cas d&#39;erreur de la premire; exemple avec le script 84.

1.
2
3
4
5
6
7.

@écho de
2>non ensemble "var=foo" || écho Erreur de la commande : ensemble "var=foo"
echo.
2>non ensemble /a "nb=09" || écho Erreur de la commande : ensemble /a "nb=09"
echo.
pause
sortie /b
OperateurPIPEPIPE

VII-L-1. Tester les deux tats d&#39;erreurs▲

Il peut tre ncessaire de tester si une commande s&#39;est excute avec ou sans erreurs et effectuer des actions diffrentes dans chacun des deux cas. La combinaison des oprateurs && et || doit se faire selon un ordre prcis afin de ne pas gnrer d&#39;erreurs. En utilisant le test de russite (&&) avant le test d&#39;erreur (||), le test de russite n&#39;est valide que lorsqu&#39;il n&#39;y a aucune erreur dans la commande et le test d&#39;erreur n&#39;est valide que lorsqu&#39;il y a une erreur au test de russite . Exemple avec le script 85:

1.
2
3
4
5
6
7.
8
9
dix.
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

@écho de Etcls
écho Etat     Mthodes     Commandes
écho ====================================


(
2>non ensemble /a "var=09"
) || (
    écho [Erreur]    1           ensemble /a "var=09"
) EtEt (
    écho [Ok]                    1           ensemble /a "var=09"
)
(
    ensemble /a "var=07"
) || (
    écho [Erreur]    1           ensemble /a "var=07"
) EtEt (
    écho [Ok]                    1           ensemble /a "var=07"
)
écho ====================================


(
2>non ensemble /a "var=09"
) EtEt (
    écho [Ok]                    2           ensemble /a "var=09"
) || (
    écho [Erreur]    2           ensemble /a "var=09"
)
(
    ensemble /a "var=07"
) EtEt (
    écho [Ok]                    2           ensemble /a "var=07"
) || (
    écho [Erreur]    2           ensemble /a "var=07"
)

écho ====================================
echo.
pause
sortie /b 0
Test_Erreur

VII-M. Les oprateurs &▲

Ces oprateurs permettent de rediriger le flux d&#39;un tampon l&#39;autre. L&#39;oprateur <& redirige l&#39;entre standard ou le flux entrant dans un tampon vers un autre; l&#39;oprateur >& redirige la sortie standard ou le flux sortant d&#39;un tampon vers un autre. Ces oprateurs ne peuvent tre utiliss qu&#39;avec des handles, toutes les redirections entre des tampons doivent se faire avec ces oprateurs.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13

@écho de
cls
3>>errlog.txt ensemble /a "var1=09" 2>Et3
3>>errlog.txt écho foo 1>Et3
3>>errlog.txt écho bar 1<Et3
3>>errlog.txt écho foobar >Et3
écho Fichier errlog.txt:
echo.
type errlog.txt
echo.
del /Q errlog.txt
pause
sortie /b 0
Operateur_SHIFTAND

VII-N. Les handles pour tampon utilisateur▲

D&#39;autres handles sont disponibles, ce sont les handles pour tampons utilisateurs. Ils sont utiliss afin de rediriger l&#39;entre standard et/ou de disposer d&#39;un ou plusieurs tampons supplmentaires lors d&#39;une excution. Les handles pour tampons utilisateurs sont les handles 3 9 et l&#39;utilisation qui est faite de ces derniers est dfinie par l&#39;utilisateur. De mme que pour les tampons du canal standard, si les donnes qu&#39;ils contiennent ne sont pas rediriges vers un fichier, celles-ci seront affiches dans la fentre de l&#39;interprteur.

Un tampon n&#39;est accessible que durant l&#39;excution qui l&#39;a charg en mmoire; ainsi lorsqu&#39;il est utilis dans une ligne de commande, ce tampon n&#39;existe que durant l&#39;excution de cette ligne de commande. Pour pouvoir utiliser l&#39;handle d&#39;un tampon utilisateur pendant l&#39;excution de plusieurs commandes, il faut que l&#39;handle dsigne toujours le mme tampon; de plus, les handles sont assigns des fichiers chargs en mmoire, il faut donc aussi un fichier charger en mmoire pour qu&#39;il puisse servir de tampon.

Les scripts batch ne gre nativement que les chanes de caractres, le fichier qui servira de tampon doit donc tre un fichier texte, il est cr au moment de la premire utilisation et doit tre supprim manuellement, car une fois cr, il est enregistr sur le disque dur.

Dans un script batch, un bloc de commandes se symbolise avec des parenthses () comme dans les conditions si o les commandes entre parenthses ne sont excut que si la condition se vrifie; ou encore dans les boucles pour o le bloc de commandes entre parenthses s&#39;excute chaque itration de la boucle. Chaque fois que l&#39;interprteur rencontre une parenthse ouvrante, il considre toutes les lignes de commandes jusqu&#39; la parenthse fermante quivalente comme faisant partie d&#39;un seul et mme bloc indissociable. Les redirections agissent aussi sur ces blocs, il est ainsi possible de rediriger la sortie standard de chaque commande du bloc en plaant une redirection avant ou aprs le bloc; la redirection agira sur la totalit du bloc.

De la mme manire, la redirection d&#39;un tampon utilisateur peut agir sur un bloc de commandes; le fait de rediriger un tampon utilisateur pour un bloc de commandes permet de lier le fichier texte et l&#39;handle pour tout le bloc de commandes. Chaque fois qu&#39;il sera fait rfrence l&#39;handle dans le bloc de commandes, l&#39;handle dsignera toujours le mme fichier texte. Le fichier sera alors accessible via l&#39;handle et via son nom. Cependant, durant l&#39;excution du bloc, le fichier ne peut ni tre vid ni tre supprim. Ainsi pour crer un bloc dans lequel l&#39;handle 3 dsigne le fichier buffer3, il faudrait utiliser la syntaxe suivante:

Syntaxe de la redirection de bloc

Sélectionnez

3>>buffer3 (

)

Dans le script 87, des chanes de caractres sont rediriges vers le tampon dsign par l&#39;handle 3, le tampon est ensuite parcouru via le nom du fichier charg dans le tampon dsign par l&#39;handle 3. The command 0>nul >&3 set /p "=xyz" sert ajouter la chane xyz au tampon dsign par l&#39;handle 3 sans retour la ligne.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16

@écho de
cls
3>>buffer3 (
1<Et3 écho Foo
1>Et3 écho Bar
0>non >Et3 ensemble /p "=Foo"
    >Et3 écho Bar
    pour /f "delims=" %%a dans (&#39;type buffer3&#39;) faire (
0>non >Et3 ensemble /p "=%%a "
)
    >Et3 echo.
)
type buffer3
del /Q buffer3
pause
sortie /b 0
Tampon_Utilisateurs

De la mme faon, il est possible d&#39;utiliser les redirections avec les blocs des conditions et des boucles; exemple avec le script 88.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21

@écho de
1>text.txt  écho foo
1>>text.txt écho bar
1>>text.txt écho foobar
si exister text.txt 9>>buffer9 (
    >Et9 écho Le fichier text.txt a t trouv.
)
écho Contenu de buffer9: Et type buffer9 Et del /Q buffer9 Et echo.
pour /f "delims=" %%a dans (&#39;type text.txt&#39;) faire (((
            écho %%a | findstr ^<foo 1>Et3
            écho %%a | findstr ^<bar 1>Et4
            écho %%a | findstr bar^> 1>Et5
        ) 5>>buffer5
    ) 4>>buffer4
) 3>>buffer3
écho Contenu de buffer3: Et type buffer3 Et del /Q buffer3 Et echo.
écho Contenu de buffer4: Et type buffer4 Et del /Q buffer4 Et echo.
écho Contenu de buffer5: Et type buffer5 Et del /Q buffer5 Et echo.
del /Q text.txt
pause
sortie
Tampon_Utilisateur_bloc_if_for

VII-O. Les pseudo-fichiers de priphrique▲

Les pseudo-fichiers de priphriques sont des alias de nom de fichier qui permettent d&#39;accder au contenu d&#39;un tampon de priphrique de la mme manire qu&#39;un fichier texte. Plusieurs priphriques sont disponibles depuis l&#39;interprteur, en voici la liste:

  • le canal standard;
  • les ports sries;
  • les ports parallles;
  • l&#39;imprimante par dfaut (seulement pour les systmes Vista et infrieurs, et certains Windows 7);
  • le priphrique auxiliaire.

VII-O-1. Le pseudo-fichier CON▲

Pour rappel le canal standard est le tampon utilis par les commandes durant leurs excutions, il est trait comme tant un priphrique du fait que l&#39;entre standard est lie par dfaut au clavier et la sortie standard est lie par dfaut l&#39;cran (la fentre de l&#39;interprteur). Le pseudo-fichier du canal standard est CON[:], il a assez peu d&#39;applications concrtes, mais en voici une qui permet de saisir un texte sur plusieurs lignes la diffrence de la commande set /p qui ne permet les saisies que sur une seule ligne.

1.
2
3
4
5
6

@écho de
pour /f "delims=" %%a dans (&#39;type CON&#39;) faire (
    écho %%a
)
pause
sortie

N.B. Pour quitter la saisie et continuer l&#39;excution du script, il faut presser les touches Ctrl+Z et appuyer sur entre. Voir l&#39;annexe A.2A.2. Insertion de caractres de contrle et de signaux pour plus de dtails.

Pseudo-fichier_CON

Le nom de fichier CON est rserv par le systme, il n&#39;est donc pas possible de crer un fichier qui porte ce nom. Les diffrentes constituantes du canal standard sont accessibles via le pseudo-fichier CON, ainsi l&#39;entre standard est accessible via CON[:]IN$, la sortie standard via CON[:]OUT$ et l&#39;erreur standard via CON[:]ERR$.

VII-O-2. Les pseudo-fichiers COMx▲

Les ports sries utilisent les pseudo-fichiers COMx, o X est le numro de port cible. Ce numro peut aller de 1 256 mme si un PC ne peut avoir 256 ports (ces numros de ports sont attribuables des ports mapps sur un rseau). L&#39;utilisation des ports est plutt simple, car il suffit de les lire ou les crire via les commandes écho (pour l&#39;criture) et type ou plus (pour la lecture). Il faut prendre en compte qu&#39;un port srie doit tre configur avec les mmes paramtres que le port distant auquel il est connect, cela peut tre fait via la commande mode COMx; l&#39;affichage des paramtres se fait avec mode COMx /status. La configuration d&#39;un port srie ne seras pas aborde dans ce document du fait de la quantit d&#39;lments prendre en compte. Vous pouvez effectuer des tests d&#39;critures/lectures sur un port srie en utilisant une loopback entre deux ports sries d&#39;un mme ordinateur l&#39;aide d&#39;un cble crois 3, 5 ou 7 fils, il suffit alors de relier les deux ports sries avec le cble crois. Les pseudo-fichiers COM1 COM9 sont rservs par le systme et les autres le seront si un port distant est mapp dessus. De mme que pour le canal standard, les entres et les sorties sont accessibles via COMx:IN$ et COMx:OUT$.

criture sur un port srie, o est la chane a envoyer par le port srie.

écho <message> >COMx

Lecture depuis un port srie.

type COMx

plus<COMx

Pseudo-fichier_COMx

VII-O-3. Les pseudo-fichiers LTPx▲

Les ports parallles utilisent les pseudo-fichiers LTPx, o X est le numro de port cible. Ce numro peut aller de 1 256. Il existe un mappage local entre port COM et LTP via la commande mode LTPx[:]=COMy[:]. L&#39;criture et la lecture s&#39;utilisent de la mme faon que pour les ports sries, via les commandes écho et type ou plus. Les pseudo-fichiers LTP1 LTP9 sont rservs par le systme et les autres le seront si un port distant est mapp dessus. De mme que pour le canal standard, les entres et les sorties sont accessibles via LTPx:IN$ et LTPx:OUT$.

VII-O-4. Le pseudo-fichier PRN▲

L&#39;imprimante par dfaut utilise le pseudo-fichier PRN et la diffrence des autres pseudo-fichiers de priphrique, il n&#39;est pas possible de lire les donnes qu&#39;il contient. Ainsi seule l&#39;criture est possible sur ce pseudo-fichier de priphrique, cela s&#39;effectue l&#39;aide d&#39;une redirection de la sortie standard. Il faut noter que sous Windows 7 (Ultimate et Entreprise seulement) et Windows Serveur 2008 R2, ce pseudo-fichier de priphrique n&#39;est plus fonctionnel. Le pseudo-fichier PRN est rserv par le systme.

VII-O-5. Le pseudo-fichier AUX▲

Le priphrique auxiliaire est mapp sur le port COM1 pour des questions de compatibilit ascendante avec les anciens systmes de la gamme Microsoft. Le mappage de ce port peut tre modifi via la commande change port, voir l&#39;aide en ligne de commande pour plus d&#39;informations. Le pseudo-fichier AUX est rserv par le systme. Si le pseudo-fichier AUX est mapp sur un autre pseudo-fichier qui possde plusieurs constituants (IN$, OUT$ ou ERR$), alors ces dernires sont accessibles via AUX:IN$, AUX:OUT$ et ventuellement AUX:ERR$.

Un script a besoin de donnes pour s&#39;excuter, il arrive parfois que la quantit de donnes ncessaires soit trs importante. Plutt que d&#39;utiliser une commande rallonge, il est possible de placer ces donnes dans un fichier texte puis de les lire avec une boucle pour. Cependant un fichier texte classique n&#39;est gure adapt ce type d&#39;opration. La solution la plus pratique est l&#39;utilisation de fichiers *.ini, ces derniers possdent une syntaxe bien dfinie qui permet une lecture intuitive et donc facilite une ventuelle modification. Les fichiers *.ini qui doivent tres utiliss par un script batch doivent tre encods avec le Code Page correspondant la langue d&#39;installation du systme afin de permettre leur utilisation par un script.

VIII-A. La syntaxe des fichiers *.ini▲

Un fichier *.ini se compose de sections qui distinguent les diffrentes parties du fichier, chaque section relate les diffrentes entres utiliser pour une opration donne. Les sections utilisent la syntaxe suivante, o est le nom que vous donnerez votre section:

[[[[<nom_de_la_section>]

Des commentaires peuvent tre ajouts afin de donner des informations facilitant la lecture du fichier. Pour insrer un commentaire, il faut utiliser le caractre ; en dbut de ligne. Exemple avec le fichier test.ini:

1.
2
3
4
5
6
7.
8
9
dix.
11
12







[[[[Section_One]



[[[[Section_Two]

Les entres d&#39;une section peuvent utiliser deux syntaxes, mais on utilise qu&#39;un des deux types de syntaxes par section. Chacune de ces deux syntaxes est utilise des fins diffrentes en fonction des besoins.

La syntaxe des entres nommes est utilise lorsqu&#39;une entre est unique dans la section. Cependant, mme si une entre nomme ne peut tre utilise qu&#39;une fois par section, elle est souvent utilise dans chaque section du fichier. La syntaxe des entres nommes est la suivante, o est l&#39;identifiant de l&#39;entre et est sa valeur:

=

Les entres non nommes quant elles sont utilises pour les oprations rptitives qui ncessitent plusieurs paramtres. Par exemple la copie de fichiers qui ncessite au moins un chemin d&#39;accs source et un chemin d&#39;accs de destination. Les entres non nommes sont crites avec les paramtres les uns la suite des autres spars par des virgules.

,,...,

VIII-B. Lecture d&#39;un fichier *.ini▲

En gnral, on utilise un seul et mme script par systme pour lire les fichiers *.ini. Celui-ci est ensuite appel par les scripts ayant besoin de lire un fichier *.ini. Un tel script pourrait ressembler au script 90.

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46
47
48.
49
50
51.
52
53
54
55
56.
57
58
59
60.
61.
62
63.
64.
65.
66.
67.
68.
69
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99
100
101.
102.
103.
104

@écho de
setlocal
setlocal enabledelayedexpansion

ensemble "ScriptName=%~n0"
ensemble "IniFile="
ensemble "IniSection="
ensemble "IniEntrie="
ensemble "CasseSensitive="
ensemble "CurrentSection="

:ParseArgs
si "%~1"=="" goto Init
si /i "%~1"=="/?" goto Help
si /i "%~1"=="-?" goto Help
si /i "%~1"=="/h" goto Help
si /i "%~1"=="-h" goto Help
si /i "%~1"=="/Aidez-moi" goto Help
si /i "%~1"=="-help" goto Help
si /i "%~1"=="/f" (
    ensemble "IniFile=%~2"
    décalage /1
    décalage /1
    goto ParseArgs
)
si /i "%~1"=="/s" (
    ensemble "IniSection=%~2"
    décalage /1
    décalage /1
    goto ParseArgs
)
si /i "%~1"=="/e" (
    ensemble "IniEntrie=%~2"
    décalage /1
    décalage /1
    goto ParseArgs
)
si /i "%~1"=="/i" (
    ensemble "CasseSensitive=/i"
    décalage /1
    goto ParseArgs
)
:BadSyntax
pour /f "delims=" %%a dans (&#39;net helpmsg 87&#39;) faire écho [[[[%~1 ] %%a
si ne pas "%~0"==":BadSyntax" endlocal
sortie /b 87

:Init
si ne pas défini IniFile (
    appel :UnknowError "/f"
    sortie /b 87
)
si ne pas exister "%IniFile%" (
    appel :UnknowError "%IniFile%"
    sortie /b 87
)
si défini IniSection goto Exec
:UnknowError
si "%~1"=="" (
    appel :BadSyntax "/s"
) autre (
    appel :BadSyntax "%~1"
)
echo.
appel :Help
endlocal
sortie /b 87

:Exec
pour /f "usebackq eol=; delims=" %%a dans (`type "%IniFile%"`) faire (
    ensemble "FixLine=%%~a"
    si "!FixLine:~0,1!"=="[" (
        pour /f "tokens=1 delims=[]" %%b dans ("%%a") faire (
            ensemble "CurrentSection=%%~b"
)
) autre (
        si %CasseSensitive% "!CurrentSection!"=="%IniSection%" (
            si défini IniEntrie (
                pour /f "tokens=1 delims==" %%b dans ("%%a") faire (
                    si %CasseSensitive% "%%~b"=="%IniEntrie%" écho %%a
                )
) autre (
                écho %%a
            )
)
)
)
goto End

:Help
echo.
écho %ScriptName% /f ^<Ini_File_Path^> /s ^<Ini_Section^> [/e^[/e^[/e^[/e^<Ini_Entrie^>] [/i]
écho %ScriptName% /?
echo.
écho     /f  Dfinit le fichier *.ini  parser.
écho     /s  Dfinit la section  renvoyer.
écho     /e  Dfinit l&#39;entre  renvoyer.
écho     /i  Dfinit que la recherche est insensible  la casse.
echo.    /?  Affiche cette aide.
echo.

:End
si ne pas "%~0"==":Help" endlocal
sortie /b 0

La lecture d&#39;une section comprenant des entres nommes peut se faire via un script semblable au script 91. Celui-ci lit le fichier stock.ini dans lequel est consign l&#39;inventaire d&#39;un bar, ainsi lorsque vous demandez au script 91 une boisson, il vous dit s&#39;il y en a et si c&#39;est votre jour de chance. Remplacez ini_reader.bat par le nom que vous donnerez au script 90.

1.
2
3
4
5
6
7.
8
9
dix.
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
45
46

@écho de
setlocal enabledelayedexpansion
ensemble "Choix1=Beer"
ensemble "Choix2=Vodka"
ensemble /a "Addition=0"
ensemble /a "NbConsommation=0"
:Serveur
ensemble ChoixClient=
echo.
écho Que voulez-vous boire?
echo.
écho     1. Bire
écho     2. Vodka
écho     3. Rien pour l&#39;instant, j&#39;attends quelqu&#39;un
écho     4. L&#39;addition, s&#39;il vous plat?
echo.
choix /c 1234 /n
ensemble "ChoixClient=%ErrorLevel%"
echo.
si %ChoixClient% LSS 3 (
    pour /f "delims=" %%a dans (&#39;ini_reader.bat /f stock.ini /s !Choix%ChoixClient%!&#39;) faire ensemble "%%a"
    si "!bar!"=="lucky" (
        écho C&#39;est votre jour de chance, on a pas encore t livr, mais il nous en reste.
) autre (
        écho Pas de chance, on a pas encore t livr.
)
    si "!foo!"=="found" (
        ensemble /a "Addition+=!foobar!"
        ensemble /a "NbConsommation+=1"
)
) autre si %ChoixClient% EQU 4 (
    goto CaisseEnregistreuse
)
temps libre /t 10 /nobreak
cls
goto Serveur
:CaisseEnregistreuse
écho a vous fera !Addition! euros.
echo.
si %NbConsommation% GEQ 3 (
    écho Vous avez trop bu pour chatteduire, vous devez me laisser vos cls.
    écho coutez, ne le prenez pas comme a: c&#39;est la loi sinon je risque un procs.
    écho Moi je vends de l&#39;alcool, je ne vous oblige pas  le boire...
)
pause
sortie /b 0

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18






[[[[Bière]

foo=a trouvé
bar=chanceux
foobar=2

[[[[Vodka]

foo=pas trouvé
bar=malchanceux
foobar=5


La lecture d&#39;une section comprenant des entres non nommes peut se faire via un script semblable au script 92. Celui-ci lit le fichier filelist.ini dans lequel sont consigns les fichiers copier et ceux supprimer. Remplacez ini_reader.bat par le nom que vous donnerez au script 90.

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

@écho de
ensemble "ScriptName=%~n0"
écho Copie des fichiers ...
pour /f "delims=" %%a dans (&#39;ini_reader.bat /f filelist.ini /s Copie&#39;) faire (
    pour /f "tokens=1-3 delims=" %%b dans ("%%a") faire (
        appel :CopyFunc "%%b" "%%c" "%%d"
)
)
pause
écho Suppression des fichiers ...
pour /f "delims=" %%a dans (&#39;ini_reader.bat /f filelist.ini /s Delete&#39;) faire (
    pour /f "tokens=1-2 delims=" %%b dans ("%%a") faire (
        appel :DeleteFunc "%%b" "%%c"
)
)
pause
sortie /b 0
:CopyFunc
écho     %~3
copie %1 %2
goto :eof
:DeleteFunc
écho     %~2
del /q %1
goto :eof
filelist.ini

Sélectionnez

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15





[[[[Copie]

.%ScriptName%.bat,.%ScriptName%_Copie1.bat,Copie 1 du script ...
.%ScriptName%.bat,.%ScriptName%_Copie2.bat,Copie 2 du script ...
.%ScriptName%.bat,.%ScriptName%_Copie3.bat,Copie 3 du script ...

[[[[Effacer]

.%ScriptName%_Copie1.bat,Suppression de la copie 1 du script ...
.%ScriptName%_Copie2.bat,Suppression de la copie 2 du script ...
.%ScriptName%_Copie3.bat,Suppression de la copie 3 du script ...

La scurit est un aspect important en informatique, les scripts batch n&#39;chappent pas la rgle. En effet, les possibilits offertes par ce langage de script sont vastes, y compris pour quelqu&#39;un de mal intentionn. Nous allons voir les diffrentes mthodes utilisables par un intrus et les solutions qu&#39;il est possible d&#39;y apporter. Cependant, les solutions exposes dans ce chapitre ne sont que des pistes de rflexion; chaque problmatique ayant des implications diffrentes, il ne peut y avoir de solution gnrique.

IX-A. Les variables▲

Contrairement d&#39;autres langages, les variables sont accessibles tout le monde ou presque. Ainsi, n&#39;importe quel programme peut accder aux variables d&#39;environnement d&#39;un autre programme, du moment que celui-ci s&#39;excute en mode utilisateur et qu&#39;il est lanc par le mme utilisateur. Seuls les programmes qui sont excuts par d&#39;autres utilisateurs chappent cette rgle, moins que le programme qui scrute les variables d&#39;un autre soit lanc par un administrateur ou par le systme (en tant qu&#39;utilisateur). Pour cette partie du chapitre, il va nous falloir le programme ProcessExplorer de SysInternals disponible cette URL: https://technet.microsoft.com/en-us/sysinternals/bb896653.aspx.

Une fois ProcessExplorer tlcharg, lancez-le en tant que simple utilisateur, il propose un affichage similaire celui ci-dessous. Les programmes surligns en rose ont t lancs par le systme (en tant qu&#39;utilisateur) et les programmes surligns en bleu ont t lancs par l&#39;utilisateur courant.

ProceXp

Dans ProcessExplorer, il est possible d&#39;afficher la ligne de commande ayant appel chaque programme (utile pour le dbogage de scripts). Cela se fait via le menu View>Select Columns…, puis dans l&#39;onglet Process Image vérifier Command Line puis validez en cliquant sur D'accord. Crez le script 93 et lancez-le, mais sans appuyer sur une touche au moment de la commande pause.

1.
2
3

@écho de
ensemble "foo=bar"
pause

Une fois le script lanc, allez dans ProcessExplorer puis cliquez sur le processus de votre batch (processus cmd.exe avec comme ligne de commande cmd /c "chemind&#39;accsdevotrescript"). Allez dans l&#39;onglet Environnement, vous pourrez y voir la variable foo et sa valeur.

ProceXp_Evironment

De ce fait, les donnes sensibles ne devraient jamais tre places dans une variable, sans quoi vous risquez de crer une faille. La solution rside en partie dans les paramtres des boucles et les paramtres d&#39;appel de fonction. Par exemple, dans le script 94, la chane bar n&#39;est jamais accessible.

1.
2
3
4
5
6
7.
8
9
dix.
11
12

@écho de
pour %%a dans (bar) faire (
    pause
    écho %%a    
    appel :Étiquette %%a
)
pause
sortie /b
:Étiquette
pause
écho %1
goto :eof

Cependant, l&#39;appel d&#39;une commande externe ou d&#39;un script avec comme paramtre la donne sensible la rendra accessible tout autre programme lanc par le mme utilisateur via la commande d&#39;appel. La meilleure solution reste la cration d&#39;un utilisateur spcifique chaque opration sensible et d&#39;appeler le script qui excute l&#39;opration via la commande runas. La donne sensible pourra alors tre place dans le registre sous une cl du type HKCUsoftware, dans ce cas la cl doit tre cre par l&#39;utilisateur spcifique la tche. Il convient galement de modifier les autorisations de la cl (ACL), cela peut-tre fait dans regedit via un clic-droit sur la cl puis slectionnez Autorisations…. Il convient d&#39;interdire toutes oprations, via l&#39;option Refuser, tout autre utilisateur et groupe sauf l&#39;utilisateur spcifique. Les autorisations du registre peuvent galement tre modifies via la commande regini, entrez regini /? dans l&#39;interprteur de commandes pour plus d&#39;informations. Par la suite, le contenu de la cl pourra tre rcupr via la commande reg query; de prfrence dans une boucle pour. Exemple avec le script 95: il est ncessaire d&#39;ajouter le fichier ipmi.reg au registre afin que le script 95 fonctionne.

1.
2
3
4
5
6
7.
8

@écho de

pour /f "usebackq skip=2 delims=" %%a dans (`reg question "HKCUsoftwareipmikey" /v chattenect`) faire (
    pour /f "tokens=3" %%b dans ("%%a") faire écho %%b
)

pause
sortie /b 0

1.
2
3
4
5
6

Windows Registry Editor Version 5.00

[[[[HKEY_CURRENT_USERSoftwareipmi]

[[[[HKEY_CURRENT_USERSoftwareipmikey]
"connect"="0123456789"

Un script de ce type pourra alors tre appel avec le script suivant (o est le nom de l&#39;utilisateur spcifique et est la commande d&#39;appel du script 95).

1.
2
3
4

@écho de
runas /User:<specific_user_name> "<cmd_script>"
pause
sortie /b 0

Il convient de modifier galement les autorisations (ACL) du script qui effectue la tche sensible afin d&#39;viter toute rcriture inapproprie du script, cela peut tre fait via un clic-droit sur le fichier, slectionnez Proprits puis l&#39;onglet Scurit. Il convient de modifier les autorisations de la mme manire que pour la cl registre. Les autorisations d&#39;un fichier peuvent aussi tre modifies via la commande icacls, entrez icacls /? dans l&#39;interprteur de commandes pour plus d&#39;informations. Une commande cacls existe aussi, mais elle est proscrire, car considre comme obsolte, son support n&#39;est pas garanti l&#39;avenir.

IX-B. L&#39;injection de commandes▲

Comme tout langage de script, le batch est sensible l&#39;injection. Cette mthode consiste insrer des commandes lors d&#39;une entre (saisie utilisateur ou lecture d&#39;un fichier texte). Cette section est donc consacre l&#39;application de la clbre maxime Never trust in user input.

The command set /p n&#39;est pas sensible l&#39;injection de commandes, cependant la variable dfinie par la commande set /p peut contenir des redirections qui injecteront la (ou les) commande(s) lors de son expansion. Exemple avec le script 97:

1.
2
3
4
5
6
7.
8

@écho de

ensemble /p foo=Entrez une chane: 
echo.
écho Vous avez entr: %foo%
echo.

pause

Si l&#39;utilisateur saisit la chane bar & echo foobar, on obtient l&#39;affichage suivant dans lequel on peut voir l&#39;excution de la commande echo foobar.

Injection_cmd

La solution est simple et repose sur l&#39;chappement, mais dans une forme que nous n&#39;avons pas encore vue. Il s&#39;agit de l&#39;chappement de chanes dans leur ensemble via les guillemets, ainsi toute chane place entre guillemets peut comporter n&#39;importe quels caractres spciaux sans que cela ne pose de problme. Si l&#39;on reprend le script 97 et qu&#39;on le modifie de la manire suivante (script 98), on obtient un script sr.

1.
2
3
4
5
6
7.
8

@écho de

ensemble /p foo=Entrez une chane: 
echo.
écho Vous avez entr: "%foo%"
echo.

pause
Escap_injection_cmd

Pour en revenir ce qui avait t dit au chapitre IILa commande set sur l&#39;initialisation de variable, il est possible d&#39;utiliser la syntaxe de la commande ensemble pour pouvoir travailler avec une variable qui risque de comporter une injection en plaant les guillemets dans la variable. Cependant la variable contiendra toujours les guillemets. Exemple avec le script 99:

1.
2
3
4
5
6
7.
8
9

@écho de

ensemble /p foo=Entrez une chane: 
ensemble foo="%foo%"
echo.
écho Vous avez entr: %foo%
echo.

pause

Il est aussi possible d&#39;utiliser la syntaxe des conditions pour tester si la saisie comporte un caractre qui pourrait poser problme et sortir du processus sans autres formes de procs. Exemple avec le script 100:

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15
16
17
18
19
20
21
22
23

@écho de
setlocal enabledelayedexpansion
ensemble "ScriptName=%~dpnx0"
ensemble /p foo=Entrez une chane: 
pour /l %%a dans (0 1 4096) faire (
    si "!foo:~%%a,1!"=="Et" (
        appel :Injection "!foo:~%%a,1!" "%foo%"
) autre si "!foo:~%%a,1!"=="|" (
        appel :Injection "!foo:~%%a,1!" "%foo%"
) autre si "!foo:~%%a,1!"=="<" (
        appel :Injection "!foo:~%%a,1!" "%foo%"
) autre si "!foo:~%%a,1!"==">" (
        appel :Injection "!foo:~%%a,1!" "%foo%"
)
)
echo.
écho Vous avez entr: %foo%
echo.
pause
sortie /b 0
:Injection
1>>log.txt écho Le caractre %1 a t dtect dans une saisie utilisateur dans le script "%ScriptName%" excut par l&#39;utilisateur "%UserName%". La saisie tait %2.
sortie

Dans le script 100, un message a t crit dans un log; cela aurait tout aussi pu tre l&#39;envoi d&#39;un mail l&#39;administrateur, la prise d&#39;une photo avec la webcam ou toute autre solution juge ncessaire.

De mme que lors d&#39;une saisie utilisateur, la lecture d&#39;un fichier texte peut poser problme. The command type et la boucle pour ne sont pas sensibles l&#39;injection. Cependant, l&#39;utilisation ultrieure des donnes lues dans le fichier peut permettre l&#39;injection. Exemple avec le script 101 et le fichier test_injection.txt:

1.
2
3
4
5
6
7.
8
9
dix.
11
12
13
14
15

@écho de
setlocal enabledelayedexpansion

pour /f "delims=" %%a dans (test_injection.txt) faire (
    ensemble str=%%a
    écho Dans la boucle: !str!
    appel :Étiquette "!str!"
)

pause
sortie /b 0

:Étiquette
écho Aprs un appel: %~1
goto :eof
test_injection.txt

Sélectionnez

1.
2

foo & echo foobar
bar
Injection_txt

On remarque que l&#39;utilisation de la variable !str! dans la boucle ne pose pas de problme tandis qu&#39;aprs l&#39;appel du :Label, elle provoque l&#39;injection. C&#39;est d au fait que la chane est passe au contexte du label par copie et que dans le contexte du corps de pour, l&#39;chappement se fait automatiquement. Une nouvelle chane tant cre pour le contexte du label, celui-ci ne considre pas la chane comme comportant un chappement. Si un chappement est ajout dans le fichier texte, cela ne change rien, et ce quel qu&#39;en soit le nombre. La seule solution est de tout traiter dans le corps de pour lorsqu&#39;une entre provient d&#39;un fichier texte, d&#39;utiliser les guillemets lors d&#39;une commande d&#39;appel ayant en paramtre une entre provenant d&#39;un fichier texte et ventuellement de tester la prsence de caractre de redirection (seulement s&#39;il n&#39;y a pas de lgitimit ces caractres).

Apprendre la programmation par script batch – Un bon serveur Minecraft
4.9 (98%) 32 votes