Variáveis de ambiente em arquivos em lote são expandidas quando uma linha é analisada. No caso de blocos delimitados por parênteses (como if defined
), o bloco inteiro conta como uma "linha" ou comando.
Isso significa que todas as ocorrências de% FOO% são substituídas por seus valores antes de o bloco ser executado. No seu caso com nada, já que a variável ainda não tem valor.
Para resolver isso, você pode ativar expansão atrasada :
setlocal enabledelayedexpansion
A expansão atrasada faz com que as variáveis delimitadas por pontos de exclamação ( !
) sejam avaliadas na execução em vez da análise, o que garantirá o comportamento correto no seu caso:
if not defined BAR (
set FOO=1
echo Foo: !FOO!
)
help set
detalha isso também:
Finally, support for delayed environment variable expansion has been added. This support is always disabled by default, but may be enabled/disabled via the
/V
command line switch toCMD.EXE
. SeeCMD /?
Delayed environment variable expansion is useful for getting around the limitations of the current expansion which happens when a line of text is read, not when it is executed. The following example demonstrates the problem with immediate variable expansion:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
would never display the message, since the
%VAR%
in bothIF
statements is substituted when the first IF statement is read, since it logically includes the body of theIF
, which is a compound statement. So the IF inside the compound statement is really comparing "before" with "after" which will never be equal. Similarly, the following example will not work as expected:set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST%
in that it will not build up a list of files in the current directory, but instead will just set the
LIST
variable to the last file found. Again, this is because the%LIST%
is expanded just once when theFOR
statement is read, and at that time theLIST
variable is empty. So the actual FOR loop we are executing is:for %i in (*) do set LIST= %i
which just keeps setting
LIST
to the last file found.Delayed environment variable expansion allows you to use a different character (the exclamation mark) to expand environment variables at execution time. If delayed variable expansion is enabled, the above examples could be written as follows to work as intended:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%