Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Batch File not setting variable

Tags:

batch-file

I'm trying to write a batch file that will simplify the generation of WebService stubs. The problem is that one of the SET commands for a variable is not setting the value. I've tried various things to get it to honour this SET but to no avail. Clearly missing something obvious. The rest of the script is working fine.

IF %1==-b (
    ECHO %2
    SET BINDINGS_FILE=%2
    SHIFT & SHIFT
    ECHO File: %BINDINGS_FILE%

    IF EXIST "%BINDINGS_FILE%" (
        SET BINDINGS=-b %BINDINGS_FILE%
    ) ELSE (
        ECHO Please enter a valid Bindings file name: %BINDINGS_FILE%.
        GOTO DONE
    )
    ECHO BINDINGS = %BINDINGS%  
)

When I execute it with the following command, it prints the bindings file as %2 but the variable into which it gets SET remains empty.

generate-stubs.bat -b wsdl/Binding.xml -p com.acme.service wsdl/WebService.wsdl

wsdl/Binding.xml
File:
Please enter a valid Bindings file name: .
Done!

Any suggestions appreciated.

like image 832
radimpe Avatar asked Jun 06 '14 09:06

radimpe


2 Answers

Batch file is setting the variable to the indicated value. BUT you are not seeing it.

In batch files lines are parsed, and then executed. Line by line or block by block (lines enclosed in parenthesis). When the parser reaches a line or a block of lines, at all points where a variable is read, the reference to the variable is removed and replaced with the value in the variable before starting to execute the block. So, if a variable changes its value inside a block, this new value will not be accesible from inside this same block. What is being executed does not include a reference to the variable but the value in the variable when the code was parsed.

To change this behaviour, and be able to read the changed value of the variable from inside the same block that changed the value, delayed expansion is needed.

When delayed expansion is enabled, the syntax to access/read a variable can be changed (where needed) from %var% to !var!. This instructs the parser not to do the initial replacement and delay the access to the value until execution of the command.

So, your code can be something like

setlocal enabledelayedexpansion 

IF "%1"=="-b" (
    ECHO %2
    SET "BINDINGS_FILE=%~2"
    SHIFT & SHIFT
    ECHO File: !BINDINGS_FILE!

    IF EXIST "!BINDINGS_FILE!" (
        SET "BINDINGS=-b !BINDINGS_FILE!"
    ) ELSE (
        ECHO Please enter a valid Bindings file name: !BINDINGS_FILE!.
        GOTO DONE
    )
    ECHO BINDINGS = !BINDINGS!  
)
like image 56
MC ND Avatar answered Nov 08 '22 16:11

MC ND


Looks like a very old post but might save someone hours of effort...

All commands within IF statement brackets "(" ")" get executed as a single block. The variable value does get changed during execution of the IF statement block (LINE 2 till LINE 5) but the changed value can ONLY be used after the current block execution completes. e.g. your code snippet below,


    1 IF %1==-b (
    2    ECHO %2
    3    SET BINDINGS_FILE=%2
    4    SHIFT & SHIFT
    5    ECHO File: %BINDINGS_FILE%
      )
    6    ECHO %BINDINGS_FILE%

Although the value of "BINDING_FLAGS" is set in Line #3, but it will take effect ONLY in the next block or next command, which means, that Line #6 will display the actual value and not LINE #5

like image 38
ash Avatar answered Nov 08 '22 15:11

ash