Batch File not setting variable - 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.

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!
)

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

Related

) was unexpected at this time. Batch error

IF "~1" == "" (
pause
set /p training_folder="Enter training folder: "
) else (
pause
set training_folder="%~1" & ::business rules file is assumed to be in here
)
pause
) was unexpected at this time. Batch error
Magoo gave you the traditional answer - Use REM instead of :: when in parentheses.
But there is another option. You can use undefined variable "expansion" anywhere within your code, even in the middle of a line. The "comment" simply expands to an empty string.
set training_folder="%~1" %= business rules file is assumed to be in here =%
An = cannot appear in variable names, except for the undocumented dynamic pseudo variables like %=ExitCode% and %=ExitCodeAscii%. An = can never appear anywhere other than the first character in the name. I use a pair at the beginning and end for the pleasing visual symmetry, and it is guaranteed to never match the name of a variable, no matter the content.
The only restriction is your "comment" cannot contain : or %.
Replace the :: with rem. As it is, there appears to be a label within a code-block, which is not usually allowed.

What is the difference between "myvar=me" and "myvar"="me"?

I've been wondering what is the difference between "myvar=me" and "myvar"="me" in a batch file?
It might make a difference to my program which is a rock, paper, and scissors game.
The difference can be easily seen on running a batch file with following lines:
#set "myvar=me"
#set "myvar"="me"
set myvar
#pause
The first line defines an environment variable with name myvar with value me.
The second line defines an environment variable with strange name myvar" with value "me.
The third line is output by Windows command interpreter after preprocessing the command line before execution and outputs all environment variables of which name start with myvar with environment variable name, equal sign and environment variable value.
And fourth line halts batch execution until a key is pressed to see output of third line in case of batch file was executed with a double click.
So the first three lines of output are:
set myvar
myvar=me
myvar"="me
For details on how to define an environment variable right with correct assigning a value read answer on:
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
It explains with text and examples why the syntax set "variable=value" is usually the best.
That depends on context.
In case of usage inside the set command it can treat quotes as a part of a variable name and a value:
>set "a"="111"
'
>set
a"="111
...
But not in this case:
>set "a=111"
'
>set
a=111
...
Internal logic of the cmd.exe is simple is that as it eats character by character and removes quotes from the most left and right parts of a string.
Here is another context (file test.bat):
#echo off
call :TEST "1111"="2222"
call :TEST "1111","2222"
call :TEST "1111";"2222"
call :TEST "1111"-"2222"
exit /b 0
:TEST
echo -%1- -%2-
'
-"1111"- -"2222"-
-"1111"- -"2222"-
-"1111"- -"2222"-
-"1111"-"2222"- --
As you see some characters treated here as a parameter separator in a command line.
Personally I prefer to write the set "var=value" without ^-escape characters before the & and ) characters which can be part of a file path.

Set one variable in another batch file

I would like to set a variable in another batch file, if it exsists. But it works only localy in the sub batch file. How can I fix this problem?
Main.bat:
SET TEMP=""
IF EXIST SUB.bat (
CALL SUB.bat
REM Returns: TEMP="" IN MAIN
ECHO %TEMP% IN MAIN
) ELSE (
SET TEMP="DEFAULT VALUE"
)
Sub.bat:
SET TEMP="OTHER VALUE"
REM Returns: TEMP="OTHER VALUE" IN SUB
ECHO %TEMP% IN SUB
Output by calling Main.bat:
TEMP="OTHER VALUE" IN SUB
TEMP="" IN MAIN
Two issues:
Your test is incorrect. Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).
Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.
Try using CALL ECHO %%TEMP%% to display the altered value and look up "delayedexpansion" for endless SO items on this frequently-encountered subject.
Second issue - which impinges on the first.
TEMP and TMP are special variablenames which specify the location of a temporary-files directory. Best not to change them as unexpected results may ensue. Use another variablename.

Batch If statement not working

Having a problem with an If statement in a batch file. I have several scripts, one will set a value to variable and store it to a text file to be read by another script. The value is either yes or no. That part works. When the next script executes, it first reads the line from the txt file and stores the value to a variable. That part works, I can echo the variable and see that it reads the line and stores it to the variable. Now, the next section is suppose to evaluate the variable and based on the result the script will either continue or exit. for some reason it always exits. Below is sample of the statement:
::****Check Value******
set /p _xexit=<xclean.txt
Echo %_xexit%
if %_xexit%=yes (
goto skip3
) else (
::CODE TO EXECUTE IF %_xexit%=no starts here
code
::AFTER THIS CODE EXECUTES, SCRIPT WILL EXIT
::My skip3
:skip3
echo "Exit Called"
wait
Exit
You have to double the =
if "%_xexit%"=="yes"

Storing multi-word strings to a file

I've recently been trying to make a program to simply store text to a file for later viewing, storing it as a .rar file for security against those who don't understand how to extract the text from the .rar (i.e. the less "techy" people)...
I have, however, encountered an error in the program that results in the <word> not expected at this time followed by the .exe closing when I input add/<word> <word>... (i.e. any multi-word string with spaces in between the words [add/<word>, however, does function properly]).
Is there a special rule that must be followed for storing multi-word strings to a .rar or a file in general (I do, however, know that there is a rule for creating/renaming folders/directories)?
The Program Segment:
:command
cls
set /p journal=<journal.rar
echo %journal%
echo.
set /p command=What would you like to do?
cls
if %command%==exit exit
if %command%==help goto help
if %command%==delete echo START; > journal.rar
if %command:~0,4%==add/ echo "%journal%""%command:~4%;" > journal.rar
if %command:~0,5%==edit/ echo %journal:%command:~5%=%;" > journal.rar
goto command
Excuse me. Your question is not clear. There are several confusing points in it, like "followed by the .exe closing" (which .exe is closing?), and the fact that your question is NOT related to .rar files in any way, nor to "storing multi-word strings". However, I can see the following points in it:
When a variable value is expanded with percent signs this way: %command% you must be aware that the variable is first expanded and then the resulting line is parsed. This mean that the value of the variable may introduce errors in the line. For example, in this line: if %command%==exit exit, if the value of command variable is add/one two three, then the line that is parsed is this: if add/one two three==exit exit that, of course, issue an error! (type if /? for further details).
The way to avoid this problem is enclosing both the variable and the comparison value in quotes; this way, if the value have several words with spaces, the whole value is grouped in the IF command for comparison purposes: if "%command%" == "exit" exit. This must be done in every IF command that use the value of the variable.
In the following line:
if %command:~0,5%==edit/ echo %journal:%command:~5%=%;" > journal.rar
you must be aware that the line is parsed from left to right; this means that you can not nest a %variable% expansion inside another one. The way to solve this problem is first complete a %normal% variable expansion, and then a !delayed! variable expansion that will take the previous expanded value. To do that, insert this line at beginning of your program:
setlocal EnableDelayedExpansion
and change previous line by this one:
if "%command:~0,5%" == "edit/" echo !journal:%command:~5%=!;" > journal.rar
For further details, type set /? and carefully read the sections about "delayed expansion".
Here is a sample that can accept multiple words:
set "command="
set /p "command=What would you like to do? "
cls
if /i "%command%"=="have lunch" goto :food

Resources