If statement ( was unexpected at this time - windows

I have a bundled if statement that checks whether java is installed and whether or not i'm at college or at home it is part of a larger piece of code but doesn't work on its own either any help would be much appreciated
Triple Checked i have the right number of brackets and equals signs and making sure no obvious mistakes were made so i'm confused as to what has gone wrong
if exist 'C:\Temporary Workspace' (set installtype=College)
where java >nul 2>nul
pause
if %errorlevel%==1 (
if %installtype%==College (
goto :college
) else (
set /P javaboolean=Java was not found is java installed? (Y/N)
if %javaboolean%==Y (
echo Please enter the path to java.exe
set /P javalocation=e.g. C:\Program Files\Common Files\Oracle\Java\javapath\java.exe
)
)
)
pause
exit
:college
echo success for college detection
pause
The error message and run time:
D:\Batch Testing>echo Checking Location...
Checking Location...
D:\Batch Testing>if exist 'C:\Temporary Workspace' (set installtype=College)
D:\Batch Testing>where java 1>nul 2>nul
D:\Batch Testing>pause
Press any key to continue . . .
( was unexpected at this time.
I expect the output to be 'success for college detection' as the directory does exist

you need to change your ifs a little bit
the first could be changed to
if exist "C:\Temporary Workspace" set installtype=College
note that the single apostrophe is not a valid quotation mark in windows cmd. And you can remove your parentheses because they are not needed.
the second could be written as
if errorlevel 1 (
because errorlevel is not %errorlevel% (for a detailed explanation, read https://devblogs.microsoft.com/oldnewthing/20080926-00/?p=20743 )
and the last could be
if .%installtype%==.College (
because when installtype is blank the if instruction makes no sense and produces syntax error; inserting the two . avoids it.
... and, as a bonus, you might want to consider to use if /i to ignore case when comparing, so College, college, COLLEGE or even cOllegE would match.

Well, there are several issues in your code. The line
if exist 'C:\Temporary Workspace' (set installtype=College)
will never set the variable installtype, because this checks whether 'C:\Temporary exists, which does not, since the apostrope ' is just an ordinary character for the Windows Command Prompt cmd. To make it work you must use quotation marks ":
if exist "C:\Temporary Workspace\" (set "installtype=College")
The trailing \ lets the condition check for existence of a directory called Temporary Workspace but not for a file with that name.
Note that I used the quoted set syntax here, which is generally recommended as it protects special characters.
The condition
if %installtype%==College (
will return a syntax error, because the variable installtype has not been set before (due to the wrong syntax you used). To avoid trouble with empty variables, quote both comparison expressions:
if "%installtype%"=="College" (
This is also described in this thread.
The command
set /P javaboolean=Java was not found is java installed? (Y/N)
will fail when in a parenthesised block of code, because the ) will unintentionally be recognised by cmd and close the block at an undesired position. Again use quotation to solve that:
set /P javaboolean="Java was not found is java installed? (Y/N)"
or:
set /P "javaboolean=Java was not found is java installed? (Y/N)"
However, the condition
if %javaboolean%==Y (
will still fail, because the queried variable javaboolean is set in the same block of code, so the returned value is the one present when the entire block is parsed, which is an empty string most probably. To overcome this, you must apply delayed variable expansion.
Put this somewhere before to enable delayed expansion:
setlocal EnableDelayedExpansion
Then replace the %-signs by exclamation marks ! (as you can see I again applied quotation here):
if "!javaboolean!"=="Y" (
Then put this somewhere after to end the environment localisation introduced by setlocal:
endlocal
Regard that all environment changes (variables, current directories) after setlocal are lost after endlocal and the state before setlocal becomes restored.
A similar problem is also described in this question and solved by this answer.
Instead of set /P just for a Yes/No decision consider to use the choice command, which does not allow to enter anything else:
rem /* The default choices are `Y` and `N`;
rem `choice` sets `ErrorLevel` to `1` when pressing `Y` and to `2` when pressing `N`: */
choice /M "Java was not found is java installed"
rem // The following means: if ErrorLevel >= 1 and if ErrorLevel < 2:
if ErrorLevel 1 if not ErrorLevel 2 (echo Yes has been chosen.)
Instead of
exit
you should use
exit /B
to only terminate the batch script but keep the hosting cmd instance alive. This is particularly helpful when you execute the batch file from a Command Prompt window rather than by double-clicking its icon in Explorer as you can view the console output then.
Instead of the string comparison
if %errorlevel%==1 (
you could also do true numeric comparison like
if %errorlevel% equ 1 (
or, if you are fine with the condition to be true if ErrorLevel is also greater than one,
if ErrorLevel 1 (
Alternatively, you could even use condition execution operators, which query the exit code:
where java > nul 2>&1 && (
rem // The code here is executed when `where` succeeds.
) || (
rem // The code here is executed when `where` fails.
)
So finally, here is the fixed script:
Code based on yours:
if exist "C:\Temporary Workspace\" (set "installtype=College")
where java > nul 2>&1
pause
if ErrorLevel 1 (
if "%installtype%"=="College" (
goto :college
) else (
set /P javaboolean="Java was not found is java installed? (Y/N) "
setlocal EnableDelayedExpansion
if "!javaboolean!"=="Y" (
endlocal
echo Please enter the path to java.exe
set /P javalocation="e.g. C:\Program Files\Common Files\Oracle\Java\javapath\java.exe "
) else endlocal
)
)
pause
exit /B
:college
echo success for college detection
pause
Variant using conditional execution (||) and the choice command:
if exist "C:\Temporary Workspace\" (set "installtype=College")
where java > nul 2>&1 || (
if "%installtype%"=="College" (
goto :college
) else (
choice /M "Java was not found is java installed"
if ErrorLevel 1 if not ErrorLevel 2 (
echo Please enter the path to java.exe
set /P javalocation="e.g. C:\Program Files\Common Files\Oracle\Java\javapath\java.exe "
)
)
)
pause
exit /B
:college
echo success for college detection
pause

Related

Incorrect output from batch script execution

i am trying to run below snippet of code on my windows server.
#echo off
set BRANCH_NAME_ID=compiler_branch
if %BRANCH_NAME_ID%==compiler_branch ( echo INSIDE COMPILER BRANCH )
echo %BRANCH_SHORT_ID%|findstr /r "^[r][0-9][0-9]*_00$" & IF %ERRORLEVEL% == 0 ( echo IN IF ) ELSE ( echo INFO else)
pause
I was expecting the only output should be INSIDE COMPILER BRANCH because, BRANCH_NAME_ID variable is referring to compiler_branch. But some reason i am also getting IN IF as well.
Ouptut:-
INSIDE COMPILER BRANCH
IN IF
Press any key to continue . . .
As per the document https://ss64.com/nt/findstr.html i notice below and wrote the script accordingly. But some reason %ERRORLEVEL% is setting to 0 in line3 of my code thought the string is not matching :-
FINDSTR will set %ERRORLEVEL% as follows:
0 A match is found in at least one line of at least one file.
1 If a match is not found in any line of any file, (or if the file is not found at all).
2 Wrong syntax
An invalid switch will only print an error message in error stream.
Am i missing something ?
Because of how the interpreter reads files (see How does the Windows Command Interpreter (CMD.EXE) parse scripts? for a massive amount of info), %ERRORLEVEL% in that line gets replaced with its current value before the line is actually run. In order to have the command run and then have the value checked correctly, put the if statement on its own line.
#echo off
set BRANCH_NAME_ID=compiler_branch
if %BRANCH_NAME_ID%==compiler_branch ( echo INSIDE COMPILER BRANCH )
echo %BRANCH_SHORT_ID%|findstr /r "^[r][0-9][0-9]*_00$"
IF %ERRORLEVEL% == 0 ( echo IN IF ) ELSE ( echo INFO else)
pause
If for some reason you absolutely insist on using & to chain commands together (there is no reason to ever do this and it only makes things worse imo), then you can enable delayed expansion and use !ERRORLEVEL! instead.
#echo off
setlocal enabledelayedexpansion
set BRANCH_NAME_ID=compiler_branch
if %BRANCH_NAME_ID%==compiler_branch ( echo INSIDE COMPILER BRANCH )
echo %BRANCH_SHORT_ID%|findstr /r "^[r][0-9][0-9]*_00$" & IF !ERRORLEVEL! == 0 ( echo IN IF ) ELSE ( echo INFO else)
pause

Filtering for multiple results in batch using IF

I was writing a batch file replicating CMD but more customized. What I am trying to do is scan %input% for multiple different results leading to different actions. To help you envision what I mean, I tried doing this:
set /p input="%cd%>"
if "%input%" == "cls" (
GOTO reset
) else (
if "%input%" == freespace (
GOTO freespace
) else (
title %input%
%input%
GOTO A
Which just crashes the CMD window running the batch file. Is there anyway I can sort for these two responses (or possibly more) using IF statements? I realize this is SIMILAR to other questions called "using multiple if statements in batch" but they are just not the same format I am trying to put the IF statements in.
You appear to be running your batch by clicking on it, which means that you will not see error messages. It's better to run batch from the command-prompt so that the messages will be visible and persistent.
There are at least two problems with the code you have presented.
The first is that you have not closed the parentheses for the else clauses so there are two pending close-parentheses at the end of the batch.
format:
if x=y (dothis
) else (
if p==q (dosomethingelse
) else (
dosomethingelseentirely
)
)
The second problem is that if is very literal with a string-match. It includes the quotes in the strings-to-be-matched, so
if "%input%" == freespace (
can never be true as input is quoted but freespace is not (unlike cls in your first if)
BTW - if /i ... will perform a case-insensitive comparison.
You don't need multiple if commands to filter multiple results in this particular problem. This is the way I would do it:
#echo off
setlocal
:A
echo/
set "input="
set /p "input=%cd%>"
call :%input% 2> NUL
if errorlevel 1 echo "%input%" is not recognized as a command...
goto A
:cls
echo Reset command, parameters: "%*"
exit /B 0
:freespace
echo FreeSpace command, parameters: "%*"
exit /B 0
In this method a call :%input% command is directly executed, so if the label exists, then the corresponding code run; otherwise, the call :nolabel command returns an ERRORLEVEL equal 2.
Each one of the subroutines ends with exit /B 0 command, so in these cases the ERRORLEVEL is zero.
If you have any doubt about a particular command, I encourage you the review its command /? help screen or search the web looking for a more extensive description...

Problems reading simple numeric values from files in Windows batch files

My colleague and I have been pulling our hair out all day over this.
We have a simple Windows batch file. We want it to read from a text file whose file path we are generating programmatically, take the single numeric value in this file, and compare it to a local variable. But we're getting completely inexplicable behavior.
The file contains a single scalar number, such as the number 2. Here's the code:
ThisAppFlagFileName=foo.txt
if not exist "%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%" (
ECHO do something here
) else (
SET /P InstalledVersion=<"%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%"
ECHO We think the file contains: %InstalledVersion%
IF %InstalledVersion% GEQ %ThisVersionInstallDataNum% (
ECHO Version %ThisVersion% of the %ThisAppVisibleName% has already been installed for this user; exiting.
GOTO TheEnd
)
)
:TheEnd
Echo END
We keep getting an error reading 2 was unexpected at this time. So we inserted some trace message and, just in case the else was problematic, stuck to two different if statements:
ThisAppFlagFileName=foo.txt
if not exist "%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%" (
ECHO do something here
)
ECHO Trace Message 1 before IF
if exist "%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%" (
ECHO Trace Message 2 after IF before CD
SET /P InstalledVersion=<%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%"
ECHO We think the file contains: %InstalledVersion%
IF %InstalledVersion2% GEQ %ThisVersionInstallDataNum% (
ECHO Version %ThisVersion% of the %ThisAppVisibleName% has already been installed for this user; exiting.
GOTO TheEnd
)
)
:TheEnd
Echo END
And we see only the first trace message (before the if statement), and not the second trace message. So our conclusion is that somehow the content of the file is being interpolated into the line if exist "%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%", but of course we don't understand why the first if not exist works but the second doesn't.
Can anyone spot the mistake, please? Environment is Windows 7 cmd.exe window, but we are hoping to deploy to both Windows 7 and Windows XP.
The issue here is that the entire IF expression is evaluated before the SET /P statement within it can be executed. InstalledVersion is not set yet, and so this invalid expression is evaluated:
IF GEQ 2 (
Nothing inside of the IF expression executes because it cannot be completely evaluated.
A solution is to enable delayed expansion and replace %InstalledVersion% with !InstalledVersion!, as described in this post.
You can also restructure the code so the GEQ comparison happens after the IF expression.
Your code have several errors. The first line:
ThisAppFlagFileName=foo.txt
missed a set command, so it is tryed to be executed as ThisAppFlagFileName command. This mean that ThisAppFlagFileName variable is NOT defined in your program, so InstalledVersion variable is never read from the file.
All references to InstalledVersion variable must use Delayed Expansion, that is, enclose they between exclamation marks instead percents and include setlocal EnableDelayedExpansion command at beginning of your program.
setlocal EnableDelayedExpansion
set ThisAppFlagFileName=foo.txt
if not exist "%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%" (
ECHO do something here
) else (
SET /P InstalledVersion=<"%HOMEPATH%\ourcompanyname\%ThisAppFlagFileName%"
ECHO We think the file contains: !InstalledVersion!
IF !InstalledVersion! GEQ %ThisVersionInstallDataNum% (
ECHO Version %ThisVersion% of the %ThisAppVisibleName% has already been installed for this user; exiting.
GOTO TheEnd
)
)
:TheEnd
Echo END
You must be aware that all variables that are modified inside parentheses must also be enclosed in exclamation marks instead percent signs. Search for "delayed expansion" for details.

find string in text file and then renaming my log file

im working on a basic .bat file.
It checks if various files exists and if they dont, it will write "ERROR" in the log file.
I then test this log file for the string "ERROR" and if it does I want to rename my log file, but i seem to be getting an error on my if statement. Heres my code..
set "filename=C:\Temp\%COMPUTERNAME%.txt"
echo Creating .txt file...
echo Getting the Computer name...
echo %COMPUTERNAME% >> filename
echo ArcGIS Desktop 10 File checker
pause
echo Looking for files.....
call:checkFileExists C:\support\msi_local\Oracle10g\marker.txt
pause
FIND "ERROR" filename
echo error level is %ERRORLEVEL%
pause
if %ERRORLEVEL% 1 (
set "newfileName=C:\Temp\%COMPUTERNAME%%_ERROR.txt"
rename fileName newfileName
)
pause
:checkFileExists
if exist %~1 (
echo Success %~1 does exist >> C:\Temp\%COMPUTERNAME%.txt
) else (
echo ERROR "C:\support\msi_local\Oracle10g\marker.txt"%~1 does not exist >> C:\Temp\%COMPUTERNAME%.txt
)
I get a error -
The syntax of teh command is incorrect.
C:\Windows>if ERRORLEVEL 1(
Where am i going wrong?
Thanks
try this:
#echo off &SETLOCAL
set "filename=C:\Temp\%COMPUTERNAME%.txt"
echo Creating .txt file...
echo Getting the Computer name...
>>"%filename%" echo %COMPUTERNAME%
echo ArcGIS Desktop 10 File checker
pause
echo Looking for files.....
call:checkFileExists "C:\support\msi_local\Oracle10g\marker.txt"
pause
FIND "ERROR" "%filename%"
echo error level is %ERRORLEVEL%
pause
if %ERRORLEVEL% equ 1 (
set "newfileName=C:\Temp\%COMPUTERNAME%_ERROR.txt"
move "%fileName%" "%newfileName%"
)
pause
:checkFileExists
if exist "%~1" (
echo Success %~1 does exist >> C:\Temp\%COMPUTERNAME%.txt
) else (
echo ERROR "C:\support\msi_local\Oracle10g\marker.txt"%~1 does not exist >> C:\Temp\%COMPUTERNAME%.txt
)
if %ERRORLEVEL% 1 (
should be
if ERRORLEVEL 1 (
And, since you're retyping the error rather than copy-pasting, note that there must be a space between the 1 and the (
The error appears that way because batch replaces any %var% with its value at that time (when it is 'parsed') and then executes the line, so batch substitutes whatever has been reported as %errorlevel% from your debug statement :) (eg 1) and then tries valiantly to work out what if 1 1 ( means.
(btw, it would be a good idea to replace if exist %~1 ( with if exist "%~1" (
This may seem redundant, removing and then replacing the quotes, BUT if you later decide to change the statement to if exist %file% ( it's only later you'll find out you'll get a crash when %file% contains a space. Best to be ever-mindful of the spaces-in-filenames problem; if you make quoting a habit, you'll be caught out less often.
)
The two syntaxes are subtly different:
Old style syntax (MS-DOS era) - check if the error level was 1 or more:
IF ERRORLEVEL 1
New style syntax - check if the %errorlevel% variable was not equal to 0:
IF %errorlevel% NEQ 0
Note that the new style syntax uses % to indicate a variable, while with the old style syntax, ERRORLEVEL is a special keyword.
The new style syntax should be preferred, because it will handle programs that return -1 on error. If the program can return negative error codes on success, you could handle errors with IF %errorlevel GEQ 1. Either way, using the %errorlevel% variable allows a lot more flexibility.
For clarity I've used upper case for keywords and lower case for variables, but it should be case sensitive either way.

How can I make an "are you sure" prompt in a Windows batch file?

I have a batch file that automates copying a bunch of files from one place to the other and back for me. Only thing is as much as it helps me I keep accidentally selecting that command off my command buffer and mass overwriting uncommitted changes.
What code would I need for my .bat file to make it output "Are you sure?", and make me type Y before it ran the rest of the file?
If anything other than Y is typed, it should exit execution on that line.
When I call exit, it closes cmd.exe which is not what I want.
You want something like:
#echo off
setlocal
:PROMPT
SET /P AREYOUSURE=Are you sure (Y/[N])?
IF /I "%AREYOUSURE%" NEQ "Y" GOTO END
echo ... rest of file ...
:END
endlocal
try the CHOICE command, e.g.
CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
There are two commands available for user prompts on Windows command line:
set with option /P available on all Windows NT versions with enabled command extensions and
choice.exe available by default on Windows Vista and later Windows versions for PC users and on Windows Server 2003 and later server versions of Windows.
set is an internal command of Windows command processor cmd.exe. The option /P to prompt a user for a string is available only with enabled command extensions which are enabled by default as otherwise nearly no batch file would work anymore nowadays.
choice.exe is a separate console application (external command) located in %SystemRoot%\System32. File choice.exe of Windows Server 2003 can be copied into directory %SystemRoot%\System32 on a Windows XP machine for usage on Windows XP like many other commands not available by default on Windows XP, but available by default on Windows Server 2003.
It is best practice to favor usage of CHOICE over usage of SET /P because of the following reasons:
CHOICE accepts only keys (respectively characters read from STDIN) specified after option /C (and Ctrl+C and Ctrl+Break) and outputs an error beep if the user presses a wrong key.
CHOICE does not require pressing any other key than one of the acceptable ones. CHOICE exits immediately once an acceptable key is pressed while SET /P requires that the user finishes input with RETURN or ENTER.
It is possible with CHOICE to define a default option and a timeout to automatically continue with default option after some seconds without waiting for the user.
The output is better on answering the prompt automatically from another batch file which calls the batch file with the prompt using something like echo Y | call PromptExample.bat on using CHOICE.
The evaluation of the user's choice is much easier with CHOICE because of CHOICE exits with a value according to pressed key (character) which is assigned to ERRORLEVEL which can be easily evaluated next.
The environment variable used on SET /P is not defined if the user hits just key RETURN or ENTER and it was not defined before prompting the user. The used environment variable on SET /P command line keeps its current value if defined before and user presses just RETURN or ENTER.
The user has the freedom to enter anything on being prompted with SET /P including a string which results later in an exit of batch file execution by cmd because of a syntax error, or in execution of commands not included at all in the batch file on not good coded batch file. It needs some efforts to get SET /P secure against by mistake or intentionally wrong user input.
Here is a prompt example using preferred CHOICE and alternatively SET /P on choice.exe not available on used computer running Windows.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
echo This is an example for prompting a user.
echo/
if exist "%SystemRoot%\System32\choice.exe" goto UseChoice
setlocal EnableExtensions EnableDelayedExpansion
:UseSetPrompt
set "UserChoice="
set /P "UserChoice=Are you sure [Y/N]? "
set "UserChoice=!UserChoice: =!"
if /I "!UserChoice!" == "N" endlocal & goto :EOF
if /I not "!UserChoice!" == "Y" goto UseSetPrompt
endlocal
goto Continue
:UseChoice
%SystemRoot%\System32\choice.exe /C YN /N /M "Are you sure [Y/N]?"
if not errorlevel 1 goto UseChoice
if errorlevel 2 goto :EOF
:Continue
echo So you are sure. Okay, let's go ...
rem More commands can be added here.
endlocal
Note: This batch file uses command extensions which are not available on Windows 95/98/ME using command.com instead of cmd.exe as command interpreter.
The command line set "UserChoice=!UserChoice: =!" is added to make it possible to call this batch file with echo Y | call PromptExample.bat on Windows NT4/2000/XP and do not require the usage of echo Y| call PromptExample.bat. It deletes all spaces from string read from STDIN before running the two string comparisons.
echo Y | call PromptExample.bat results in YSPACE getting assigned to environment variable UserChoice. That would result on processing the prompt twice because of "Y " is neither case-insensitive equal "N" nor "Y" without deleting first all spaces. So UserChoice with YSPACE as value would result in running the prompt a second time with option N as defined as default in the batch file on second prompt execution which next results in an unexpected exit of batch file processing. Yes, secure usage of SET /P is really tricky, isn't it?
choice.exe exits with 0 in case of the user presses Ctrl+C or Ctrl+Break and answers next the question output by cmd.exe to terminate the batch job with N for NO. For that reason the condition if not errorlevel 1 goto UserChoice is added to prompt the user once again for a definite answer on the prompt by batch file code with Y or N. Thanks to dialer for the information about this possible special use case.
The first line below the batch label :UseSetPrompt could be written also as:
set "UserChoice=N"
In this case the user choice input is predefined with N which means the user can hit just RETURN or ENTER (or Ctrl+C or Ctrl+Break and next N) to use the default choice.
The prompt text is output by command SET as written in the batch file. So the prompt text should end usually with a space character. The command CHOICE removes from prompt text all trailing normal spaces and horizontal tabs and then adds itself a space to the prompt text. Therefore the prompt text of command CHOICE can be written without or with a space at end. That does not make a difference on displayed prompt text on execution.
The order of user prompt evaluation could be also changed completely as suggested by dialer.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
echo This is an example for prompting a user.
echo/
if exist "%SystemRoot%\System32\choice.exe" goto UseChoice
setlocal EnableExtensions EnableDelayedExpansion
:UseSetPrompt
set "UserChoice="
set /P "UserChoice=Are you sure [Y/N]? "
set "UserChoice=!UserChoice: =!"
if /I not "!UserChoice!" == "Y" endlocal & goto :EOF
endlocal
goto Continue
:UseChoice
%SystemRoot%\System32\choice.exe /C YN /N /M "Are you sure [Y/N]?"
if not errorlevel 2 if errorlevel 1 goto Continue
goto :EOF
:Continue
echo So you are sure. Okay, let's go ...
endlocal
This code results in continuation of batch file processing below the batch label :Continue if the user pressed definitely key Y. In all other cases the code for N is executed resulting in an exit of batch file processing with this code independent on user pressed really that key, or entered something different intentionally or by mistake, or pressed Ctrl+C or Ctrl+Break and decided next on prompt output by cmd not terminating the batch job.
For even more details on usage of SET /P and CHOICE for prompting user for a choice from a list of options see answer on How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Some more hints:
IF compares the two strings left and right of the comparison operator with including the double quotes. So case-insensitive compared is not the value of UserChoice with N and Y, but the value of UserChoice surrounded by " with "N" and "Y".
The IF comparison operators EQU and NEQ are designed primary for comparing two integers in range -2147483648 to 2147483647 and not for comparing two strings. EQU and NEQ work also for string comparisons, but result on comparing strings in double quotes after a useless attempt to convert left string to an integer. EQU and NEQ can be used only with enabled command extensions. The comparison operators for string comparisons are == and not ... == which work even with disabled command extensions as even command.com of MS-DOS and Windows 95/98/ME supported them. For more details on IF comparison operators see Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files.
The command goto :EOF requires enabled command extensions to really exit batch file processing. For more details see Where does GOTO :EOF return to?
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.
choice /?
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?
See also:
This answer for details about the commands SETLOCAL and ENDLOCAL.
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
It explains the reason for using syntax set "variable=value" on assigning a string to an environment variable.
Single line with multiple commands using Windows batch file for details on if errorlevel X behavior and operator &.
Microsoft documentation for using command redirection operators explaining the redirection operator | and handle STDIN.
Wikipedia article about Windows Environment Variables for an explanation of SystemRoot.
DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/
The choice command is not available everywhere. With newer Windows versions, the set command has the /p option you can get user input
SET /P variable=[promptString]
see set /? for more info
Here a bit easier:
#echo off
set /p var=Are You Sure?[Y/N]:
if %var%== Y goto ...
if not %var%== Y exit
or
#echo off
echo Are You Sure?[Y/N]
choice /c YN
if %errorlevel%==1 goto yes
if %errorlevel%==2 goto no
:yes
echo yes
goto :EOF
:no
echo no
Here's my go-to method for a yes/no answer.
It's case-insensitive also.
This just checks for the errors given by the input and sets the choice variable to whatever you require so it can be used below in the code.
#echo off
choice /M "[Opt 1] Do you want to continue [Yes/No]"
if errorlevel 255 (
echo Error
) else if errorlevel 2 (
set "YourChoice=will not"
) else if errorlevel 1 (
set "YourChoice=will"
) else if errorlevel 0 (
goto :EOF
)
echo %YourChoice%
pause
You can also use 'Choice' command
#echo off
echo Sure?
CHOICE /C YN
IF %ERRORLEVEL% EQU 1 goto CONTINUE
IF %ERRORLEVEL% EQU 2 goto END
:END
exit
:CONTINUE
echo hi
pause
If you want to the batch program to exit back to the prompt and not close the prompt (A.K.A cmd.exe) you can use "exit /b".
This may help.
set /p _sure="Are you sure?"
::The underscore is used to ensure that "sure" is not an enviroment
::varible
if /I NOT "_sure"=="y" (
::the /I makes it so you can
exit /b
) else (
::Any other modifications...
)
Or if you don't want to use as many lines...
Set /p _sure="Are you sure?"
if /I NOT "_sure"=="y" exit /b
::Any other modifications and commands.
Hope this helps...
Here is a simple example which I use in a backup (.bat / batch) script on Windows 10, which allows me to have different options when making backups.
...
:choice
set /P c=Do you want to rsync the archives to someHost[Y/N]?
if /I "%c%" EQU "Y" goto :syncthefiles
if /I "%c%" EQU "N" goto :doonotsyncthefiles
goto :choice
:syncthefiles
echo rsync files to somewhere ...
bash -c "rsync -vaz /mnt/d/Archive/Backup/ user#host:/home/user/Backup/blabla/"
echo done
:doonotsyncthefiles
echo Backup Complete!
...
You can have as many as you need of these blocks.
You can consider using a UI confirmation.
With yesnopopup.bat
#echo off
for /f "tokens=* delims=" %%# in ('yesnopopup.bat') do (
set "result=%%#"
)
if /i result==no (
echo user rejected the script
exit /b 1
)
echo continue
rem --- other commands --
the user will see the following and depending on the choice the script will continue:
with absolutely the same script you can use also iexpYNbutton.bat which will produce similar popup.
With buttons.bat you can try the following script:
#echo off
for /f "tokens=* delims=" %%# in ('buttons.bat "Yep!" "Nope!" ') do (
set "result=%%#"
)
if /i result==2 (
echo user rejected the script
exit /b 1
)
echo continue
rem --- other commands --
and the user will see:
I would do it in the following way to make sure the testing and variables are correct during looping etc..
:: rem at the top of the script
setlocal enabledelayedexpansion
:: choice example
CHOICE /C YNC /M "Continue? Press Y for Yes, N for No or C for Cancel."
If /I "[!errorlevel!]" NEQ "[1]" ( GOTO START_OVER )
There are so many answers, but none of them seems to be simple and straight forward. This is the code I am using:
choice /M "Do you want to continue?"
if %errorlevel% EQU 1 (
... run your code lines here
)
First, open the terminal.
Then, type
cd ~
touch .sure
chmod 700 .sure
Next, open .sure and paste this inside.
#!/bin/bash --init-file
PS1='> '
alias y='
$1
exit
'
alias n='Taskkill /IM %Terminal% /f'
echo ''
echo 'Are you sure? Answer y or n.'
echo ''
After that, close the file.
~/.sure ; ENTER COMMAND HERE
This will give you a prompt of are you sure before continuing the command.
Open terminal. Type the following
echo>sure.sh
chmod 700 sure.sh
Paste this inside sure.sh
#!\bin\bash
echo -n 'Are you sure? [Y/n] '
read yn
if [ "$yn" = "n" ]; then
exit 1
fi
exit 0
Close sure.sh and type this in terminal.
alias sure='~/sure&&'
Now, if you type sure before typing the command it will give you an are you sure prompt before continuing the command.
Hope this is helpful!

Resources