J'ai deux exemples de fichiers de commandes très simples:
Assigner une valeur à une variable:
@echo off
set FOO=1
echo FOO: %FOO%
pause
echo on
Ce qui, comme prévu, aboutit à:
FOO: 1
Press any key to continue . . .
Cependant, si je place les deux mêmes lignes dans un bloc IF NOT DEFINED:
@echo off
IF NOT DEFINED BAR (
set FOO=1
echo FOO: %FOO%
)
pause
echo on
Cela a pour résultat inattendu :
FOO:
Press any key to continue . . .
Cela ne devrait avoir rien à voir avec le SI, il est clair que le bloc est en cours d'exécution. Si je définis BAR au-dessus du if, seul le texte de la commande PAUSE est affiché, comme prévu.
Ce qui donne?
Question de suivi: Existe-t-il un moyen d'activer l'expansion retardée sans setlocal?
Si je devais appeler cet exemple de fichier de commandes depuis un autre, l’exemple définit FOO, mais uniquement LOCAL.
Par exemple:
testcaller.bat
@call test.bat
@echo FOO: %FOO%
@pause
test.bat
@setlocal EnableDelayedExpansion
@IF NOT DEFINED BAR (
@set FOO=1
@echo FOO: !FOO!
)
Cela affiche:
FOO: 1
FOO:
Press any key to continue . . .
Dans ce cas, il apparaît que je dois activer l’extension retardée dans l’appelant, ce qui peut être fastidieux.
la source
!
, utilisez^^^!
(évitez-le deux fois). Sinon, la fonction "expansion retardée" le mangera.Le même comportement se produit également lorsque les commandes se trouvent sur une seule ligne (
&
séparateur de commandes):L'explication de Joey est mon préféré. Notez cependant que
enabledelayedexpansion
cela ne fonctionne pas sous Windows NT 4.0 (et je ne suis pas sûr de Windows 2000).Concernant votre question de suivi, non, il n’est pas possible d’en
EnableDelayedExpansion
passersetlocal
. Cependant, le comportement initial qui vous a été opposé peut être utilisé pour résoudre ce deuxième problème: l’astuce consiste àendlocal
placer sur la même ligne les valeurs des variables dont vous avez besoin.Voici votre
test.bat
modifié:Mais voici une autre solution à ce problème: utilisez une procédure dans le même fichier au lieu d’un bloc en ligne ou d’un fichier externe.
la source
Si cela ne fonctionne pas de cette façon, l'expansion des variables d'environnement est probablement retardée. Vous pouvez l'éteindre
cmd /V:OFF
ou utiliser des points d'exclamation à l'intérieur de votre if:la source
Cela se produit parce que votre ligne avec
FOR
commande n’évalue qu’une fois. Vous avez besoin d'un moyen de le réévaluer. Vous pouvez simuler une expansion retardée avec laCALL
commande:la source
Il est à noter que cela fonctionne si c'est une seule commande sur la même ligne.
par exemple
sera effectivement mis
FOO
à 1. Vous pouvez alors faire une autre vérification telle que:Hey, je n'ai jamais dit que c'était joli. Mais si vous ne voulez pas vous mêler de la problématique de setlocal ou de l'expansion retardée, la solution de contournement est rapide.
la source
Parfois, comme je l’ai fait dans mon cas, lorsque vous avez besoin d’être compatible avec les systèmes existants, tels que les anciens serveurs NT4 où l’extension retardée ne fonctionne pas ou pour une raison quelconque ne fonctionne pas, vous aurez peut-être besoin d’une autre solution.
Si vous utilisez Delayd Expansion, il est également recommandé d’inclure au moins le lot d’enregistrement:
Si vous souhaitez simplement une approche plus lisible et simple, voici d'autres solutions:
qui fonctionne comme ceci:
et encore une solution pure de cmd:
cela fonctionne comme ceci:
et ceci est complet SI ALORS ELSE solution de syntaxe:
cela fonctionne comme ceci:
la source