Definindo Variáveis nos Scripts em Lote do Windows

2

Eu preciso definir algumas variáveis com base em um argumento para um script em lotes do Windows.

@echo off       
if [%1]==[] (
    echo "Usage: xxx <AAA|ZZZ>"
) else (
    if [%1]==[AAA] (
        SET SOURCE_DIR=c:\dirA
    ) else if [%1]==[ZZZ] (
        SET SOURCE_DIR=c:\dirZ
    ) 
    echo Source dir is: %SOURCE_DIR%
)

Quando eu chamo o script acima com o parâmetro AAA , recebo a saída

Source dir is: c:\dirA

após a segunda chamada. A partir de então, quando alterno entre AAA e ZZZ , recebo esse padrão:

C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA
C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA

Parece que estou manipulando uma variável global que está disponível mesmo depois que o script foi concluído. Isso sozinho não me incomoda, mas a nova configuração só está disponível após o script terminar é um problema, já que o resto do meu script depende dele (obviamente).

Qual é o uso correto de variáveis locais neste contexto? Como explicar o comportamento estranho da "configuração do estado diferido" acima?

Obrigado!

    
por raoulsson 31.08.2009 / 14:33

2 respostas

2

Variáveis em um arquivo de lote são, por padrão, expandidas no início da execução do script; você precisa usar a expansão atrasada, que está disponível com o "!" delimitador:

echo Source dir is: !SOURCE_DIR!

Isso só funciona se a expansão atrasada estiver habilitada para o interpretador de comandos, que por padrão é não ; então você precisa ativá-lo ao iniciar o interpretador, usando CMD.EXE /V .

Você também pode ativá-lo usando esta declaração no seu arquivo de lote:

setlocal ENABLEDELAYEDEXPANSION

Mais informações aqui .

    
por 31.08.2009 / 14:41
1

Eu poderia ter lidado com isso um pouco mais simples ...

@ECHO OFF       
SET SOURCE_DIR=
IF /I [%1]==[AAA] SET SOURCE_DIR=c:\dirA
IF /I [%1]==[ZZZ] SET SOURCE_DIR=c:\dirZ
IF [%SOURCE_DIR]==[] (
    ECHO "Usage: xxx <AAA|ZZZ>"
    EXIT 1
) 
ECHO Source dir is: %SOURCE_DIR%

Eu tenho que admitir, estou um pouco confuso sobre o porquê de isso funcionar quando o exemplo da pergunta não funciona. Meu melhor palpite é que é um problema de escopo. Como no exemplo, a variável SOURCE_DIR foi definida dentro dos parens, seu valor no escopo raiz permanece inalterado. Meu script altera SOURCE_DIR no escopo raiz.

Quanto ao motivo pelo qual o truque de Expansão Atrasada faz com que ele capte a mudança que foi feita com um nível de escopo mais profundo, parece que a expansão acontece no início de cada mudança de escopo. Então, atrasando, você está basicamente forçando-o a reexpandir depois de retornar ao escopo raiz.

    
por 31.08.2009 / 16:36