If statement in Windows Batch file - windows

I have been stuck on this silly if statement, whatever i do, I cannot get the if statment to go to the correct label.
Hitting 'y' works, cmd-prompt stops at START DEPLOY
BUT, if I type 'n' cmd prints START DEPLOY then goes to end, instead of going direct to the cancel label.
Can you help?
:getConfirmation
set /p confirmDeploy =Confirm deployment of code [y/n] ?:
if "%confirmDeploy%"=="y". goto deployCode
if "%confirmDeploy%"=="n". goto cancelDeploy
:deployCode
ECHO START DEPLOY
goto end
:cancelDeploy
ECHO DEPLOY CANCELLED
goto end

Try this:
#echo off
:getConfirmation
set /p confirmDeploy=Confirm deployment of code [y/n] ?:
if %confirmDeploy%==y goto :deployCode
if %confirmDeploy%==n goto :cancelDeploy
:deployCode
ECHO START DEPLOY
goto end
:cancelDeploy
ECHO DEPLOY CANCELLED
goto end

If we ignore the fact that required input was y. or n. (due to the . in the if comparison), nobody noticed the ACTUAL problem with c14kaa's script (except Nick DeVore but didn't say why). The original script had the line
set /p confirmDeploy =Confirm deployment of code [y/n] ?:
Nick mentioned that this did not put the response into the variable. That is because it was putting the response into "confirmDeploy " (the space is part of the variable name, just another foible of cmd's input parsing). Thus when c14kaa used %confirmDeploy%, it would have expanded to %confirmDeploy% (i.e. been taken literally) unless that variable had been set elsewhere. I can only assume that c14kaa had turned off echoing because the fact that confirmDeploy did not substitute (or contained something other than y or n) would have been a big clue. It would have also revealed the problem with the . in the if statement.
As for the other suggestions, having "" around the variable (and hence needed in the matching string) is preferred to stop syntax errors when the variable is blank (generating the statement 'if == y', what jeb means by "failing"), the : before the label name in the goto is ignored and there needs to be a space after the /I in John's version (even though the if command has only one option, some commands have many and they can be put together such as in "findstr /ivn ..." so the space marks the end of the list).
The only other comment I would make is that c14kaa assumes that the user will always enter the correct response (y or n) because otherwise the script will "fall through" into the :deployCode section (probably not the ideal default behaviour). This explains the response obtained to the suggestion by Matt (echo bad input). Since the response was being put into confirmDeploy<space> it meant that both tests (using confirmDeploy without the space) failed.
Taking all of the above leaves us with Reny's version (with some explanation added).

You're on the right track, just needed to clean up syntax and spacing errors. This will work:
#echo off
:getConfirmation
set /p confirmDeploy=Confirm deployment of code [y/n] ?:
if /I "%confirmDeploy%"=="y" goto deployCode
if /I "%confirmDeploy%"=="n" goto cancelDeploy
REM added goto getConfirmation in case of invalid responses
goto getConfirmation
:deployCode
ECHO START DEPLOY
goto end
:cancelDeploy
ECHO DEPLOY CANCELLED
goto end

The problem is that neither of your tests work. You're checking for the user entering something like y. or n. (but I don't think you can actually enter anything that will match).
Try with:
if "%confirmDeploy%".=="y". goto deployCode
if "%confirmDeploy%".=="n". goto cancelDeploy
echo bad input
goto getConfirmation
...

try this too:
#echo off
:getConfirmation
set /p confirmDeploy=Confirm deployment of code [y/n] ?:
if /I%confirmDeploy%==y goto :deployCode
if /I%confirmDeploy%==n goto :cancelDeploy
:deployCode
ECHO START DEPLOY
goto end
:cancelDeploy
ECHO DEPLOY CANCELLED
goto end
The /I argument makes it case-insensitive.

Related

(BATCH) Program shuts down without any error verbose at all

I'm working on a small log clearing application, and was creating a section where the user could deploy a bot to clear Windows event logs automatically given a specific time.
During a test of the bot setup, I got to the part where the program asks the user what types of logs they want cleared, and then the program just randomly quit, without displaying any error messages at all.
Here's the section where the shut down occurs:
:bot.noexist.15
if %bot.logtype%=="all" set bot.logtype=all
if %bot.logtype%=="All" set bot.logtype=all
if %bot.logtype%=="Application" set bot.logtype=app
if %bot.logtype%=="application" set bot.logtype=app
if %bot.logtype%=="Security" set bot.logtype=sec
if %bot.logtype%=="security" set bot.logtype=sec
if %bot.logtype%=="System" set bot.logtype=sys
if %bot.logtype%=="system" set bot.logtype=sys
if %bot.logtype%=="application, security" set bot.logtype=app,sec
if %bot.logtype%=="application, system" set bot.logtype=app,sys
pause
if %bot.logtype%=="security, application" set bot.logtype=app,sec
if %bot.logtype%=="security, system" set bot.logtype=sec,sys
if %bot.logtype%=="system, application" set bot.logtype=app,sys
if %bot.logtype%=="system, security" set bot.logtype=sec,sys
pause
echo %bot.logtype%
pause
goto bot.noexist.14
I haved narrowed down the location of the problem. It is in between the first two pauses.
Maybe I'm just totally blind, but for the life of me, I cannot see what it wrong here. I don't see any typos, any mis-typed code, nothing.
Edit: because so many are wondering, I DID previously set bot.logtype="%bot.logtype%".
I would recommend using Choice command instead to avoid allowing user to type, instead just let them select from a list:
#echo off
echo select one:
echo [1] For Application
echo [2] For Security
echo [3] For System
echo [4] For System and Security
echo [5] For System and Application
echo [6] For Security and Application
echo [7] For Security and System
echo [8] For All (Application, Security and System)
choice /C 12345678
goto :%errorlevel%
goto :eof
:1
echo Clear Application logs here
goto :eof
:2
echo Clear Security logs here
goto :eof
:3
echo Clear System logs here
goto :eof
:4
echo Clear System and Security logs here
goto :eof
:5
echo Clear System and Application logs here
goto :eof
:6
echo Clear For Security and Application
goto :eof
:7
echo Clear Security and System logs here
goto :eof
:8
echo Clear All logs here
The actual answer:
Let's go through the part that is throwing errors step by step -
Assume the value of %bot.logtype% is "security, application".
if %bot.logtype%=="security, application" set bot.logtype=app,sec
This is fine, now %bot.logtype% is equal to app,sec.
if %bot.logtype%=="security, system" set bot.logtype=sec,sys
:: Equivalent to:
:: if app,sec=="security, system" …
:: sec=="security, system" was unexpected at this time.
The problem is the commas in the new value of %bot.logtype%.
There are a few ways to fix this:
Method 1
Add a goto label statement -
if %bot.logtype%=="security, system" set bot.logtype=sec,sys & goto finish
:: if …
:finish
:: Code here
Method 2
Surround your new value in "" again -
if %bot.logtype%=="security, application" set bot.logtype="app,sec"
Method 3
Don't use commas -
if %bot.logtype%=="security, application" set bot.logtype=app/sec
This fluff is going to stay because it might be relevant to those who find this question in the future.
Q1 - Is the value of %bot.logtype% never going to be nul?
If %bot.type% is based around user-input you will have problems, or if there is ever going to be a case where it is not set when you start comparing it.
You can handle this within your if statements by adding extra characters to compare to. The most common is "" (the reason being Q2):
if "%emptyVar%"=="" echo emptyVar is empty
:: Can be done with any character(s)
if #%emptyVar%==# echo emptyVar is empty
Q2 - Is the contents of %bot.type% surrounded by ""?
When comparing a variable that has a value with spaces in it, it must be surrounded by "" to prevent errors. If not, then your if statement expands like so:
set "myStr=string with spaces"
if %myStr%==value echo.
:: expands to
if string with spaces==value
:: which returns
"with" was not expected at this time
You can fix this by encapsulating the variable in "" when it is being compared:
set "myStr=string with spaces"
if "%myStr"=="string with spaces" echo true
:: returns true
Q3 - Have you heard of the IF /I switch?
As per the IF command line documentation:
If Command Extensions are enabled IF changes as follows:
IF [/I] string1 compare-op string2 command
...the /I switch, if specified, says to do case insensitive string
compares. The /I switch can also be used on the string1==string2 form
of IF. These comparisons are generic, in that if both string1 and
string2 are both comprised of all numeric digits, then the strings are
converted to numbers and a numeric comparison is performed.
By utilising this you could cut your IF statements down by half.
So:
if %bot.logtype%=="Security" set bot.logtype=sec
if %bot.logtype%=="security" set bot.logtype=sec
Becomes:
if /i %bot.logtype%=="security" set bot.logtype=sec

Windows .batch Choice command always chooses the same choice no matter input

I'm doing a project to help myself learn batch a little better. I have code which is meant to be a "UI" of sorts.
The snippet I have an issue with is this:
:install_check
if exist UI (
echo UI is already installed; reinstall?
CHOICE
if Errorlevel 1 goto :del
if Errorlevel 2 goto :return
cls && goto :install_check
)
goto :install_yes
I know the naming conventions and some of the coding stuff isn't perfect, but I really see no reason why every time it runs it goes to :del no matter what I type in for choice.
I've changed the choice switches and moved it around to be all in one line but it still doesn't want to work. The if that it is nested in is meant to check if a file is present on the computer, so it is a requirement but also may be the issue?
I tried looking around on this site but nothing will help my issue, any help is gladly accepted!!
Check the errorlevels in reverse-order.
if errorlevel n
means if errorlevel is n or greater
hence, errorlevel 2 will be interpreted as true for if errorlevel 1
As a solution has already been determined, the following example, (using your existing label names), restructures your code a little:
:install_check
ClS
If Not Exist "UI" GoTo install_yes
Choice /M "UI is already installed; reinstall"
If Errorlevel 2 GoTo return
GoTo del
If the next line/label in your code is :del, you may also remove line six.If the name UI belonged to a directory instead of a file then you'd change the third line to If Not Exist "UI\" GoTo install_yes.
ERRORLEVEL doesn't update inside control blocks like IF statements unless you use !ERRORLEVEL! instead of %ERRORLEVEL% and use this command at the start of your code: setlocal ENABLEDELAYEDEXPANSION
see http://batcheero.blogspot.ca/2007/06/how-to-enabledelayedexpansion.html

Batch File not working for the given input

Following is the batch file that I have created, for any input its only showing is "NO INPUT PROVIDED" string, I tried searching on google and tried many things but non solved my problem.
#echo off
ECHO Please provide input... Valid input is :: Y/y (For changing path) or N/n (For not changing the path).
SETLOCAL
SET /p change=
if "%~1" equ "" GOTO ERROREND
if /I "%change%" equ "Y" GOTO YES
if /I "%change%" equ "N" GOTO NO
:YES
ECHO Y SELECTED.
GOTO SUCCESS
:NO
ECHO N SELECTED.
GOTO SUCCESS
:ERROREND
ECHO Input not recognized.
GOTO FAILURE
:SUCCESS
ECHO Task completed succcess fully.
pause
:FAILURE
ECHO NO INPUT PROVIDED.
pause
Help needed. Thank you for reading this question.
if "%~1" equ "" GOTO ERROREND
means 'if the first parameter to the batchfile is empty', so if you were to run this batch from the prompt as
yourbatchname something
then something is the first parameter.
You probably menat to use "%change%", not `"%~1".
Note: if not defined change is probably a better test.
Note: Simply pressing Enter when prompted by a set /p does not set the variable to empty. It leaves the value unchanged. Best to use
set "var="
set /p var=....
Note: batch simply charges on, instruction by instruction. It has no concept of 'end-of-procedure'. Consequently, if your entry is neither Y nor N (once you've got the %~1 issue resolved) batch will simply continue execution past the if statements to the next - the ECHO Y SELECTED.

Trying to conditionally change a file path in a windows batch script

I have a simple script that launches an XML file path in Notepad++
Unfortunately, the generated file path for some of the files is incorrect and I'm trying to compensate for it in the script (ideal fix is clearly to resolve the path issue but at the moment this is not an option).
Here is what I have, apologies for the code I'm very new to Batch Script...
set /p filePath= Enter file path:
if "%filePath%" == "1" goto xmlMenu
else if "%filePath%" == "file://path/of/file/*/*/*/*/A/*.XML"
set filePath="file://path/of/file/*/*/*/*/B/*.XML"
goto openXML
I would like the filePath variable to inherit the rest of the path from the user input but at the moment its explicitly setting the path with the wildcards. There also seems to be a problem with the way I have stated the condition as it appears to set the path to /B/*.XML regardless of the else if condition.
There are many errors, but as you say, youre new.
First, if the filepath you enter is "1" then you should arrive safely at xmlmenu.
The next line will generate an error because with an else clause,
the If-true instruction must be (parenthesised)
the ( must occur on the same physical line as the if
the sequence ) else ( must all be on the same physical line (which need not be the same as the if)
In any case, the else is redundant. If the condition is not true, the jump will not happen, hence the next statement line will be executed.
if...==... is true if the string on the left is identical to the sring on the right, hence you would need for the entered string to be absolutely identical to file://path/of/file/*/*/*/*/A/*.XML for the if to be true. The action-statment also must be on the same physical line as the if, so this is a second source of syntax errors.
the set is then executed, assigning that famous string (in quotes) to the variable filepath. And then we're off to openxml.
Note that \ is a path separator in Windows; / is a switch-specifier.
Now - if you were to explain what you want to do - perhaps enter a filename which may be somewhere in a directory structure and if it's found then assign what? to the variable filepath. One or two examples would be a good idea.
This should get a usable system going. The numeric check is incomplete, but would be adequate. I've not made it bullet-proof against a user determined to break it...
#ECHO OFF
SETLOCAL
:again
SET "filepath="
set /p filePath="Please enter filepath as yyyymmdd : "
IF NOT DEFINED filepath GOTO :EOF
if "%filePath%" == "1" goto xmlMenu
:: test to see whether entered data is numeric
SET /a "filepath=%filepath%" 2>nul
IF %filepath%==0 echo invalid entry - numerics only, please&GOTO again
IF %filepath% lss 19800100 GOTO badymd
IF %filepath% gtr 20991231 GOTO badymd
SET filepath=\path\prefix\%filepath:~0,4%\%filepath:~4,2%\%filepath:~6,2%
:: This is just to show the filepath constructed
ECHO filepath is "%filepath%"
IF NOT exist "%filepath%\A\*.xml" ECHO "%filepath%\A\*.xml" does NOT exist&GOTO again
IF NOT exist "%filepath%\B\*.xml" ECHO "%filepath%\B\*.xml" does NOT exist&GOTO again
SET "filepath=%filepath%\B\*.xml"
goto openXML
:badymd
ECHO invalid entry - 4 digits FOR year, 2 FOR month an 2 FOR day, please
GOTO again
:xmlmenu
ECHO AT xmlmenu&GOTO :eof
:openxml
ECHO AT openxml with filepath="%filepath%"&GOTO :eof
GOTO :EOF
Obviously, change the path prefix to suit.
For an input of 20140220, the path ....\2014\02\20 would be constructed. Then there's a check for and this +\B\*.xml - I can only presume both must exist to proceed to openxml.

windows bat files: a %random% number as answer to an question

i am making a simple little text game in a bat file.
now, i reached a point where i want the bat file to generate a random number (using %random%); and then it will popup for 2 secs (using echo and timeout). then you should enter it in a if /p .
if you enter the right one, it will goto sb3. if its not the right one, it will goto gameover.
is this even possible?
cls
echo remember these
set ran=%random%
echo %ran%
timeout 2
cls
set /p sb2=what was the numbers? if you fail the game will quit.
if %sb2%==%ran% goto sb3
currently, whatever you type will proceed to sb3.
Do you have a code path for the alternative? If you just have the if ... goto then it will just continue with the next statement if the condition wasn't met. If your code looks like this:
if %sb2%==%ran% goto sb3
:sb3
...
then it's not surprising that you'll always end up there.
You need to jump out explicitly:
if %sb2%==%ran% goto sb3
goto :eof
:sb3
...

Resources