insert a variable into a variable in batch - batch-file

I'm trying to insert a variable into a variable, I've tried this, but it didn't work:
set gabriel-ctCODE=fmfg1
set /p user=Username:
set /p password=Password:
set /p ctCODE=ctCODE:
if %password%== %%user%-pass% set /a loginerrorlevel=%loginerrorlevel%+1
pause
if %ctCODE%== "%%user%-ctCODE%" set /a loginerrorlevel=%loginerrorlevel%+1
if not %loginerrorlevel%== 2 goto login.incorrect
goto :aftercommand
I would like to insert the "user" variable into this variable: %%user%-pass%
Could you help me please?

Here is your batch code rewritten for validating entered credential data:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "gabriel-ctCODE=fmfg1"
set "gabriel-pass=xxxyyy"
set "UserName="
set /P "UserName=User name: "
set "Password="
set /P "Password=Password: "
set "ctCODE="
set /P "ctCODE=ctCODE: "
call set "UserPass=%%%UserName%-pass%%"
call set "UserCode=%%%UserName%-ctCODE%%"
set "LoginErrorLevel=0"
if "!Password!" == "!UserPass!" set /A LoginErrorLevel+=1
if "!ctCODE!" == "!UserCode!" set /A LoginErrorLevel+=1
if not %LoginErrorLevel% == 2 goto LoginIncorrect
echo Entered credential data are valid for login.
goto EndBatch
:LoginIncorrect
echo Enter credential data not valid for login.
:EndBatch
endlocal
On set /P the user of the batch file has the freedom to enter nothing in which case the environment variable keeps its current value or is still not defined if not defined before. The batch code above makes sure that the 3 environment variables are not defined before prompting the user.
The batch file user has also the freedom to enter anything including critical characters for batch file execution like %, > <, ", etc. which is the reason for enclosing the variable=value assignments in double quotes as this results in interpreting the entered characters as literal characters and using delayed expansion on string comparisons.
Read the answers on Why is no string output with 'echo %var%' after using 'set var = text' on command line? and on Password system does not work for more details.
To get the values of the environment variables gabriel-ctCODE and gabriel-pass when the user enters gabriel (in any case) as user name, the command SET must be used with appropriate string and additionally the command CALL to expand the environment variable inside the variable string. Read for example answer on Pass environment variables to subshell CMD for details.
An arithmetic expression is everything after set /A which is interpreted by Windows command line interpreter completely different than usual.
For details on behavior of the commands SETLOCAL and ENDLOCAL read this answer.
For a basic understanding of the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?

Related

How to save a variable to a batch file?

This is my code:
set /p name=user save name
if %name%==[""]
cd c:\users\student\desktop\login system\usersXD
echo set "name=%name%"> %name%.bat
My code is not working. and i will like to load them up to view
I suggest following code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
goto PromptName
:ErrorInvalid
echo/
echo Error: The character !InvalidChar! is not allowed in name.
echo/
endlocal
:PromptName
set "Name="
set /P "Name=User save name: "
rem Has the user not input anything?
if not defined Name goto PromptName
rem Remove all double quotes from input string.
set "Name=%Name:"=%"
rem Has the user input just double quotes?
if not defined Name goto PromptName
rem Check if the input string contains any character not allowed in a file name.
setlocal EnableDelayedExpansion
for %%I in ("<" ">" ":" "/" "\" "|") do if not "!Name:%%~I=!" == "!Name!" set "InvalidChar=%%~I" & goto ErrorInvalid
if not "!Name:?=!" == "!Name!" set "InvalidChar=?" & goto ErrorInvalid
if not "!Name:**=!" == "!Name!" set "InvalidChar=*" & goto ErrorInvalid
endlocal
cd /D "%UserProfile%\Desktop\login system\usersXD"
echo set "Name=%Name%">"%Name%.bat"
endlocal
The file name of the batch file to create must be enclosed in double quotes because it could contain a space or one of these characters &()[]{}^=;!'+,`~ which require enclosing the file name in double quotes.
This batch file should not be stored in directory %UserProfile%\Desktop\login system\usersXD on having file extension .bat as it could be overwritten during execution if the user enters a name the name of the batch file. It would be safe to have this batch file in that directory with file extension .cmd.
The batch file is still not 100% fail-safe despite the checks already added, but the user input string itself cannot result anymore in an exit of batch file execution because of a syntax error.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
cd /?
echo /?
endlocal /?
for /?
goto /?
if /?
rem /?
set /?
setlocal /?
See also:
Wikipedia article listing the predefined Windows environment variables like UserProfile
Single line with multiple commands using Windows batch file explaining the operator &
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Microsoft documentation page Using command redirection operators explaining the redirection operator >
Microsoft documentation page Naming Files, Paths, and Namespaces listing which characters are not allowed in file/folder names
This should work to save a variable in a bat file
If I remember
(
Echo set test=%
Echo set test=%test%
Echo set test=%test%
)>Test.bat

How to show what user typed in this command?

please help! I was looking for the answer all over the internet.
Here's my code:
#echo off
title var test
:question
set a1=This
set a2=Is
set a3=a
set a4=Var
set a5=Test
choice /c 12345 /m "press a number"
if errorlevel=5 set num=5&goto answer
if errorlevel=4 set num=4&goto answer
if errorlevel=3 set num=3&goto answer
if errorlevel=2 set num=2&goto answer
if errorlevel=1 set num=1&goto answer
:answer
echo now change the answer.
set /p a%num%=
FOR /F "tokens=1-6" %%1 IN ("%a1% %a2% %a3% %a4% %a5% a%num%") DO echo %%1 %%2 %%4 %%5.&echo You typed=%%6
pause
goto question
As you can see I made the user select a number between 1 and 5 to change the specific word. But when I try same kind of code to show what he typed doesn't work :(
Environment variables should never begin with a digit and using a digits for loop variables should be also avoided. Run in a command prompt window call /? and output is the help for this command explaining how batch file arguments can be referenced with %0, %1, %2, ... which explains why environment variables with digit as first character and loop variables with a digit are not good in general even on being
a%num% in set of FOR does not reference the value of environment variable a1 or a2 or a3 or a4 or a5. It is just the name of the environment variable. The for loop is not necessary at all.
#echo off
title var test
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%
pause
goto question
The command line call echo You typed: %%a%num%%% is parsed by Windows command processor before execution of the command line on number 3 entered to call echo You typed: %a3%. This command line is parsed a second time because of command call resulting in replacing %a3% by the value of environment variable a3 and so echo outputs the expected string.
It would be also possible to replace call echo You typed: %%a%num%%% by
setlocal EnableDelayedExpansion
echo You typed: !a%num%!
endlocal
The usage of delayed environment variable expansion results also in double parsing the command line before execution of command echo. For more details see How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Please read also this answer for details about the commands SETLOCAL and ENDLOCAL.
The two lines below in batch code above are also not really good taking into account that the user can really enter anything.
echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%
For example if the user enters number 1 and on next prompt enters:
Your user name is:& setlocal EnableDelayedExpansion & echo !UserName!& endlocal & rem
Then the batch file does something completely different than designed for and outputs the user's account name.
Secure would be the batch code:
#echo off
title var test
setlocal EnableExtensions DisableDelayedExpansion
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
setlocal EnableDelayedExpansion
echo !a1! !a2! !a3! !a4! !a5!.
echo You typed: !a%num%!
endlocal
pause
goto question
Now the user input string cannot modify anymore the command lines executed by Windows command processor.
A solution with the useless FOR loop would be:
setlocal EnableDelayedExpansion
for /F tokens^=1-6^ eol^= %%A in ("!a1! !a2! !a3! !a4! !a5! !a%num%!") do echo %%A %%B %%C %%D %%E.&echo You typed: %%F
endlocal
eol= is necessary to output everything correct also if use enters number 1 and next a string starting with a semicolon. The FOR options string cannot be enclosed in double quotes in this case like "tokens=1-6 eol=" because of this would define " as end of line character and nothing is output if user enters number 1 and enters next a string starting with ". The equal sign and the space must be escaped with ^ to be interpreted as literal characters by cmd.exe on double parsing the entire for command line before execution of command for.
Note: The FOR loop solution does not work correct on user enters for first variable value the special command line string as posted above. So it is also not really secure.

Comparing "+" symbol with variable entered by user using if statement in batch file

I have some problems with batch file. The file should accept input of 2 numbers from user and then accept input of sign. After that compare users entered sign with "+" sign, however it's not working.
Maybe you will be able to understand better from my code:
echo please enter first number
set /p number0=
echo please enter second number
set /p number1=
echo enter one of the numbers - ^+ - / ^*
set /p symbol="set the variable: "
echo %symbol%
set plus=+
echo %plus%
pause
if /i "%symbol%" EQU "+"(
echo your choice is to sum up the numbers
pause
set /a answ = %number0% + %number1%
echo answer:
echo %answ%
)
I already tried using if /i %symbol% == plus, tried to use quotes in any combination I was able to imagine. I tried to assign operator plus variable like this set /p plus="+" then using "" around symbol variable, and so on.
But still nothing works, after I reach part where variable should be compared with symbol + my batch file just crashes. All variables are assigned correctly.
That's the link to see full file if it's necessary, however please note that full file isn't written in English language: https://1drv.ms/u/s!Ap4-t2P-Igzihb5shQZLNkKySEWOrQ.
I have found a way to do same thing without if statement. It turns out I can just do this:
set /p number1=
set /p number2=
set /p symbol=
set /a answ=%number1%%symbol%%number2%
I suggest this code:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set Number1=
set /P "Number1=First number: "
set Number2=
set /P "Number2=Second number: "
:EnterOperator
set Operator=
set /P "Operator=Math. operator: "
if not defined Operator goto EnterOperator
if "!Operator!" == "+" goto EvaluateExpression
if "!Operator!" == "-" goto EvaluateExpression
if "!Operator!" == "*" goto EvaluateExpression
if "!Operator!" == "/" goto EvaluateExpression
goto EnterOperator
:EvaluateExpression
set /A Result=Number1 %Operator% Number2
echo The result is: %Result%
endlocal
Read the help output on running a command prompt window set /? carefully regarding to arithmetic expressions. On using just the environment variable names Number1 and Number2 as it is possible in an arithmetic expression, the string entered by the user can be also nothing or not an integer number in which case Windows command interpreter replaces the not existing environment variable or the invalid string by value 0 on evaluation of the arithmetic expression.
The arithmetic symbol respectively operator must be evaluated using delayed environment variable expansion before evaluating the arithmetic expression as otherwise Windows command interpreter could output an error message because of an invalid operator or something completely different is done depending on what the user inputs on prompt for the operator.
Please note that a division by zero is still possible by this code.
See answer on Use IF statement on variables with unacceptable symbols (e.g. / or :) for the reason using delayed environment variable expression on comparing the operator strings before using in arithmetic expression with expansion before executing this command line. See also Why is no string output with 'echo %var%' after using 'set var = text' on command line? with general information about SET syntax.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?

Password system does not work

Here is the code I am trying to solve:
set /p password= Password (Put in Guest if guest login):
if %password% == %pass% goto desktop
if not %password% == %pass% goto bootscreentwo
if %password% == Guest goto ltddesktop
:desktop
it is for a "Mini operating system" made in batch.
The code does not work if the user just hits RETURN or ENTER resulting in environment variable password still not being defined as not defined with an initial value above line with set /p.
This results on IF condition with immediate expansion of environment variable password and with pass having value xxx in the command line:
if == xxx goto desktop
The left string is missing and therefore batch execution is exited because of a syntax error as it can be seen on running the batch file without #echo off at top of the batch file from within a command prompt window instead of double clicking on the batch file.
Also if the entered string contains for example | or & or < or > the immediate expansion of environment variable password result on parsing the IF condition line in a syntax error with an immediate exit of batch file execution.
The common solution to get characters with special meaning interpreted as literal characters is putting both strings to compare in double quotes. The double quotes are also compared by IF and not just the string between the double quotes. Therefore it is necessary to double quote both strings.
if "%password%" == "%pass%" goto desktop
if not "%password%" == "%pass%" goto bootscreentwo
if "%password%" == "Guest" goto ltddesktop
Which characters require double quotes around a string is explained in help of Windows command interpreter output by running in a command prompt window cmd /? in last paragraph on last output help page. The redirection operators >, < and | are missing in this list as those characters can't be used in file names.
But there is still a problem even on using double quotes around the strings to compare if the batch file user enters a string containing 1 or more double quotes as this results with immediate environment variable expansion again in a syntax error on execution of IF command line.
The solution is using delayed environment variable expansion as explained by help of command SET output on running in a command prompt window set /?.
First suggestion for the batch code on where the user has to enter guest for using guest access:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "pass=xxx"
:EnterPassword
set "password="
set /P "password=Enter "Guest" for guest login. Password: "
if "!password!" == "" goto EnterPassword
rem Case-sensitive password string compare using delayed expansion.
if "!password!" == "!pass!" goto desktop
rem Case-insensitive password string compare using delayed expansion.
if /I "!password!" == "Guest" goto ltddesktop
echo bootscreentwo
goto :EOF
:desktop
echo Label desktop
goto :EOF
:ltddesktop
echo Label ltddesktop
goto :EOF
Windows command interpreter does implicitly do an endlocal on exiting batch file execution on executing goto :EOF resulting in restoring previous command process environment.
Second suggestion for batch code with guest being default password:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "pass=xxx"
:EnterPassword
set "password=guest"
set /P "password=Press ENTER for guest login. Password: "
rem Case-insensitive password string compare using delayed expansion.
if /I "!password!" == "Guest" goto ltddesktop
rem Case-sensitive password string compare using delayed expansion.
if "!password!" == "!pass!" goto desktop
echo bootscreentwo
goto :EOF
:desktop
echo Label desktop
goto :EOF
:ltddesktop
echo Label ltddesktop
goto :EOF
Please note that enabled delayed expansion results in interpreting ! anywhere in batch code as beginning of an environment variable reference. So be careful on using ! for example in an ECHO line as the exclamation mark must be escaped to be interpreted as literal character. It would be best to use endlocal before further processing the batch file if the values of password and pass are no longer needed after this batch code block.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "pass=xxx"
:EnterPassword
set "password=guest"
set /P "password=Press ENTER for guest login. Password: "
rem Case-insensitive password string compare using delayed expansion.
if /I "!password!" == "Guest" endlocal & goto ltddesktop
rem Case-sensitive password string compare using delayed expansion.
if "!password!" == "!pass!" endlocal & goto desktop
endlocal
echo bootscreentwo with pass and password not defined anymore.
goto :EOF
:desktop
echo Label desktop with pass and password not defined anymore.
goto :EOF
:ltddesktop
echo Label ltddesktop with pass and password not defined anymore.
goto :EOF
pass and password are not defined anymore after the string compares, except those two environment variables existed already before execution of SETLOCAL command in second line in which case their original values are restored by ENDLOCAL. See this answer for details about the commands SETLOCAL and ENDLOCAL.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
goto /?
if /?
rem /?
set /?
setlocal /?

Windows script doesn't work when user types in a whitespace

I'm writing a Windows script in batch. I have a problem with whitespaces in variables. When the user types in a space, the script breaks.
Here's the part of my script:
:package
SET /P packageName="Set package name:"
IF [%packageName%] EQU [] (
ECHO Empty package name.
goto package
) ELSE (
set "packageName=%packageName: =%"
echo %packageName%
pause
)
This schould work:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:package
SET /P packageName="Set package name:"
IF "%packageName%"=="" (
ECHO Empty package name.
goto package
) ELSE (
set packageName=%packageName: =%
echo !packageName!
pause
)
There are two modifications to your script:
[%packageName%] EQU [] was replaced with "%packageName%"==""
I've added SETLOCAL ENABLEDELAYEDEXPANSION and changes echo %packageName% with echo !packageName!
The second point is because you are changing the value of a variable inside an IF-construction. As the interpreter doesn't know what the new value will be at "compile" time, you have to evaluate the variable at run time. That's why you need SETLOCAL ENABLEDELAYEDEXPANSION and !...! instead of %...%. This forces the expansion at run time.
I suggest to use this code:
#echo off
setlocal EnableDelayedExpansion
:package
rem Predefine variable packageName with a single double quote as value.
rem This value is kept if the user just hits RETURN or ENTER on prompt.
rem The single double quote is removed 2 command lines below if the user
rem does not enter anything or it is overwritten by user entered string.
set "packageName=""
set /P "packageName=Set package name: "
rem Remove double quotes from entered string. This is necessary to
rem avoid a syntax error on next command line with the IF condition.
set "packageName=!packageName:"=!"
if "!packageName!" == "" (
echo Empty package name.
goto package
) else (
set "packageName=%packageName: =%"
echo Package name with spaces: %packageName%
echo Package name without spaces: !packageName!
pause
)
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
if /?
set /?
setlocal /?
Especially the help pages output on execution of if /? should be read carefully and completely as this helps explains delayed expansion as it must be used here on examples.
See also the output of the 2 echo lines in ELSE branch in code above to understand what is the difference between referencing a variable with percent signs or with exclamation marks in blocks defined with ( ... ).
Your script is almost correct except for "variable search/replace" which its position is to be before "IF"
#echo off
:package
set /p packagename="set package name:"
set packagename=%packagename: =%
if [%packagename%] equ [] (
echo empty package name &goto package
) else (echo %packagename%)

Resources