Whenever the user of a batch file is prompted for a string using set /P
the user has the freedom to
- enter nothing at all by pressing simply just RETURN or ENTER which results in the environment variable is still not defined after prompt if it was not defined before, or the variable keeps its current value if it was already defined before, or
- enter really anything including a string which could result in an exit of batch execution because of a syntax error somewhere in batch code later or an unwanted behavior.
Let us look on the line
if %append%==return (
If environment variable is not defined before with a default value and the batch user enters nothing, this line expands during preprocessing step to:
if ==return (
This command line is of course invalid and results in an exit of batch processing because of a syntax error.
Now let us assume the user enters the string:
I want to append this string.
Then the IF command line expands to:
if I want to append this string.==return (
And of course also this command line is invalid.
The other answerers suggested to enclose the two strings to compare in double quotes, i.e. use the command line:
if "%append%"=="return" (
But does that really solve all possible issues?
Is the code now really safe against any user input.
Let us look what happens if the user enters the string:
" is a double quote. It should be used around paths like "%ProgramFiles(x86)%".
The IF command line expands now to:
if "" is a double quote. It should be used around paths like "%ProgramFiles(x86)%""=="return" (
And this command line is again invalid and results in an exit of the batch file because of a syntax error.
So how to make batch code safe against really any user input?
The solution is using delayed environment variable expansion wherever the user entered string is referenced.
Example:
@echo off
setlocal EnableDelayedExpansion
echo.
echo Enter EXIT to exit this batch script.
:PromptUser
echo.
set "UserInput=Nothing^!"
set /P "UserInput=Please enter a string: "
if /I "!UserInput!" == "exit" goto EndBatch
echo You entered: !UserInput!
goto PromptUser
:EndBatch
echo.
echo Thanks for running this example batch code.
echo.
echo The batch file ends in 3 seconds ...
endlocal
%SystemRoot%\System32\ping.exe localhost -n 4 >nul
By using delayed expansion the user entered string can't result in a invalid or unexpected command line in later code. This is also important for the command line
echo !append!>>%filename%
It is important to have no space character left of >>
or this space character is also written into the file as trailing space.
But delayed expansion is also important here in case of user enters for example just 2
which would result with echo %append%>>%filename%
in
echo 2>>%filename%
which does not append the character 2
to the file, but would append STDERR to the file which results in an empty line written to the file.
Delayed expansion is also needed for this string entered by the user:
(Var1 > 0x2F) && (Var1 < 0x3A)
which should be written with ECHO into the file as entered and not what Windows command interpreter would produce after expanding the string when using echo %append%>>%filename%
.