134

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.

13 Answers 13

221

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
7
  • 8
    The only thing I would add is an additional SET AREYOUSURE=N before the prompt in order to clear the choice if you already ran the script before in that command window. Without it the default will remain the previously selected choice.
    – isapir
    Commented Dec 26, 2014 at 21:05
  • 6
    @Igal I'm pretty sure that the setlocal and the endlocal should take care of that. %AREYOUSURE% won't exist anymore after the endlocal.
    – user837703
    Commented Jun 12, 2015 at 20:30
  • 1
    @dudeprgm you're probably right. I think that I missed those in my code.
    – isapir
    Commented Jun 14, 2015 at 5:34
  • 8
    ...would be more valuable with some explanatory words about the important two lines.
    – Wolf
    Commented Feb 3, 2017 at 10:27
  • @Joe Maybe he can't because (like me) he doesn't (yet) understand them. So if you do, it would be amazing if you could expand on your answer or link to resources explaining it :) Commented Nov 20, 2019 at 9:07
43

try the CHOICE command, e.g.

CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
3
  • 12
    <show off>Though this is relatively new. It was added in MS-DOS 6 in 1993 or 1994, so it may not work with all implementations</show off> Commented Mar 7, 2010 at 18:10
  • 13
    example of how to actually use choice here computerhope.com/issues/ch001674.htm Commented Nov 4, 2016 at 8:35
  • 2
    doesn't actually explain what to do after that command. sure it links to a web page, but that page could be removed at any time. Mofi's answer is much better
    – cantsay
    Commented Sep 17, 2022 at 20:18
29

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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 & exit /B
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 exit /B

: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 & exit /B
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
exit /B

: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:

  1. 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".
  2. 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.
  3. The command goto :EOF requires enabled command extensions to really exit the batch file processing. For more details see Where does GOTO :EOF return to? There can be used also exit /B which works even with disabled command extensions, but outputs an error message on disabled command extension. exit /B 2>nul can be used in any execution environment to exit the processing of a batch file without showing even an error message. In the two batch file examples is used exit /B because of being shorter than goto :EOF. Both commands work in the examples as the execution environment is completely defined at top of the batch file with the first two command lines.

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 /?
  • exit /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

See also:

3
  • 1
    choice.exe was also around in DOS since 6.0 Commented Jun 19, 2020 at 14:59
  • 1
    @BrianMinton That is not right. There was available the 16-bit application CHOICE.COM by default on MS-DOS 6.0, MS-DOS 7.0, Windows 95 and Windows 98. But there was no choice.exe installed by default on Windows NT4, Windows 2000 and Windows XP. CHOICE.COM could be used also on NT4, Windows 2000 and Windows XP, but it would be better to use 32-bit choice.exe from appropriate resource kit. See Rob van der Woude´s page about CHOICE. The options are partly different between CHOICE.COM and choice.exe. However, the question is not about DOS.
    – Mofi
    Commented Jun 19, 2020 at 15:16
  • 1
    You have a Yes/Cancel situation here ("Cancel" being disguised as "No"), Don't do if Cancel do CancelAction else do YesAction. Instead, do if Yes do YesAction else do CancelAction or if not Yes do CancelAction else do YesAction. The point is, do not check use Cancel condition in the if. Use the Yes condition. This also applies to CHOICE. CHOICE can return 0 or 255 (which is neither 1 nor 2), in which case your program behaves incorrectly.
    – dialer
    Commented Jan 11, 2021 at 9:32
17

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

0
12

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
3
  • after the Y put the command you want to happen. That's what the ... are for :)
    – Bob Smith
    Commented Apr 24, 2017 at 14:16
  • I meant: %errorlevel% is always an integer value. See here for documentation including an example.
    – Stephan
    Commented Apr 24, 2017 at 14:31
  • Finally , somebody who understood the question..
    – Mike Q
    Commented Jan 25, 2022 at 20:39
3

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
2

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
2

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

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...

0

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.

0
0

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:

enter image description here

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:

enter image description here

0

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

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.

2
  • 1
    Maybe in bash, but certainly not in batch.
    – Stephan
    Commented May 28, 2020 at 18:07
  • Oh. I guess not. It only works for terminal commands not batch commands. Sorry for the false information. Commented May 28, 2020 at 18:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.