-2

I am trying to use the choice command in a batch script to take the default input if the user doesn't want to stop kicking off a report. I wrote the below script but instead of waiting 10 seconds and kicking off the report, it is recursively echo-ing the first line of the code over and over until I kill the script. Is there something wrong that I am doing?

My Code:

CHOICE /C YN /N /T 10 /D N /M "Run Report Y or N?"
IF ERRORLEVEL 1 SET REPORT=RunTheReport:
IF ERRORLEVEL 2 SET REPORT=DontRunIt:

ECHO You chose to run %REPORT%

P.S: I replaced the report commands with an echo statement but it is still not working

Ryan Bemrose
  • 9,018
  • 1
  • 41
  • 54
Vibhav MS
  • 143
  • 1
  • 6
  • 18
  • 1
    The `if ErrorLevel ` syntax means **if ErrorLevel is equal to *or greater than* **; you could either reverse the order of your `IF` statements, or use `if %ErrorLevel% EQU ` for an equality check... – aschipfl Aug 01 '16 at 19:54
  • Possible duplicate of [Batch ERRORLEVEL not working properly](http://stackoverflow.com/questions/38493401/batch-errorlevel-not-working-properly) – aschipfl Aug 01 '16 at 19:58
  • @RyanBemrose, `REPORT` will always be set to `DontRunIt:` here, so it does matter; nevertheless, for the rest (concerning "recursively echo-ing [...] code [...] until I kill the script") we cannot tell as the OP does not show enough code... – aschipfl Aug 01 '16 at 20:03
  • The code doesn't let me input anything and this is all the code that I have which I am testing right now. There is nothing else. Even if I were to use an EQU, the code should be able to allow me to input data which it doesn't – Vibhav MS Aug 01 '16 at 20:11
  • Close, then re-open Cmd Prompt window to clear its memory. Save the code as batch file and run again from Cmd window. Any error? – sambul35 Aug 01 '16 at 20:16
  • That is all the code I have which is why it is confusing me so much. I have rebooted my machine as well just in case any memory had to be cleared and this is happened in two machines. Were you guys able to run my code in your machines? – Vibhav MS Aug 01 '16 at 20:17
  • What's your Windows versions? – sambul35 Aug 01 '16 at 20:25
  • @RyanBemrose, you are totally right, I was reading `set` but thinking of `goto`... – aschipfl Aug 01 '16 at 20:26
  • @RyanBemrose The question example is sufficient for testing. I was able to test it _as is_ with some corrections, which is expected with most questions. – sambul35 Aug 01 '16 at 20:33
  • @RyanBemrose - The example in the question was sufficient and I added a screenshot of the problem I was facing after you asked. What else would you think will complete the question? – Vibhav MS Aug 01 '16 at 20:45
  • @aschipfl Turns out we were both right. – Ryan Bemrose Aug 01 '16 at 21:30
  • The code you posted cannot repeat the `choice` command, not on Windows 10, not on earlier Windows versions, not even on MS-DOS, so you need to show more code... – aschipfl Aug 01 '16 at 21:48
  • ...unless there are files with the base names `echo` or `set` in the current directory and extensions listed in the `%PATHEXT%` variable... – aschipfl Aug 01 '16 at 22:20
  • Or if a previous batch run was not exited properly. – sambul35 Aug 02 '16 at 00:11

2 Answers2

4

You have found one of the few instances where the difference between .cmd and .bat is important.

The sample you posted works correctly, when you save that code to a file named script.bat.

script.bat

CHOICE /C YN /N /T 10 /D N /M "Run Report Y or N?"
IF ERRORLEVEL 1 SET REPORT=RunTheReport
IF ERRORLEVEL 2 SET REPORT=DontRunIt

ECHO You chose to run %REPORT%
  • When the user presses Y the errorlevel is set to 1. The first IF line matches and sets REPORT=RunTheReport. The second IF line does not match, and the end result is Run.
  • When the user presses N the errorlevel is set to 2. The first IF line matches and sets REPORT=RunTheReport. The second IF line matches and sets REPORT=DontRunIt. The end result is Don't Run.

In a .bat file, the IF ERRORLEVEL ladder will continue and execute every matching SET line. The last matching SET will be the one used.


If you save that same code to a file named script.cmd CMD behaves a little bit differently. One difference is that the SET command now sets ERRORLEVEL to 0 when it successfully sets a variable.

  • When the user presses Y the errorlevel is set to 1. The first IF line matches and sets REPORT=RunTheReport. The second IF line does not match, and the end result is Run, just like the .bat case.
  • When the user presses N the errorlevel is set to 2. The first IF line matches, sets REPORT=RunTheReport, and sets ERRORLEVEL to 0. The second IF line then does NOT match. The end result is also Run, which is wrong.

In a .cmd file, only the first matching SET line is run.

Therefore, if your file is named with a .cmd extension, you must reverse the order of the IF ERRORLEVEL lines, so that the correct one is the only one executed.

script.cmd

CHOICE /C YN /N /T 10 /D N /M "Run Report Y or N?"
IF ERRORLEVEL 2 SET REPORT=DontRunIt
IF ERRORLEVEL 1 SET REPORT=RunTheReport

ECHO You chose to run %REPORT%

There is an easy way to avoid this issue and make your code work in both types of file. The IF ERRORLEVEL N syntax is deprecated. It is confusing because it matches as greater-than-or-equal, rather than equal. Instead, use the newer IF %errorlevel% EQU N syntax.

script2.{bat|cmd}

CHOICE /C YN /N /T 10 /D N /M "Run Report Y or N?"
IF %ERRORLEVEL% EQU 1 SET REPORT=RunTheReport
IF %ERRORLEVEL% EQU 2 SET REPORT=DontRunIt

ECHO You chose to run %REPORT%
Community
  • 1
  • 1
Ryan Bemrose
  • 9,018
  • 1
  • 41
  • 54
  • Thanks a lot. This makes total sense but I had used it as a .BAT file and I mentioned in my original description when I said it is a batch script. I probably should've added a .BAT in the parentheses. – Vibhav MS Aug 01 '16 at 21:35
  • Great finding! +1, although this question does not seem worth to be answered in my opinion, because the original code cannot cause repetitions of the `choice` command line... – aschipfl Aug 01 '16 at 21:50
  • Any _normal_ question is worth answering if you can to honor the person who asked it and others who search for similar answers. Leaving a comment instead of answering the question makes search more difficult. Also, a comment may be difficult for a novice to interpret correctly. Downvoting someone's answer to promote your own is very cheap tactics either, negatively affecting SO reputation. – sambul35 Aug 01 '16 at 21:52
  • @sambul35 Not sure if that was directed at me, but I didn't downvote anything. I originally voted to close the question because, as aschipfl pointed out, OP still hasn't given anything that could explain the repetitions. But I don't downvote correct answers. – Ryan Bemrose Aug 01 '16 at 22:01
  • Thanks for clarification. It was a generic remark. I extensively discussed highly negative downvoting practices on Meta, especially serial ones, submitting several proposals to this effect, hotly debated as you may expect. :) – sambul35 Aug 01 '16 at 22:17
1

Save as test.bat and run this script. It works well. Edited to show different approaches possible. It runs a bit faster:

@echo off
CHOICE /C YN /N /T 10 /D N /M "Run Report Y or N?"
IF "%errorlevel%"=="2" (SET "REPORT=DontRunIt:"
) else (SET "REPORT=RunTheReport:")
ECHO You chose to run %REPORT%
timeout 5
exit /b
sambul35
  • 1,058
  • 14
  • 22
  • Thanks. I am guessing its an issue with Windows 10. I logged into a terminal server and tested in another OS and my code was working too. Weird. Thanks again for the help. – Vibhav MS Aug 01 '16 at 20:27
  • This was tested in Win10. Not sure if WinXP supports CHOICE command. Also, you might have disabled CMD extensions. Just add `setlocal enable extensions` at the beginning of script. – sambul35 Aug 01 '16 at 20:30
  • This code does not work, hence -1; look at @RyanBemrose's [answer](http://stackoverflow.com/a/38708399) which demonstrates how to achieve the correct selection... – aschipfl Aug 01 '16 at 23:10
  • ...retracting my downvote as your code is fixed now; just a side note: you could use `if %ErrorLevel% EQU 2` to do a true numeric comparison (although it does not make a difference in this situation)... – aschipfl Aug 02 '16 at 22:35
  • @aschipfl Just wanted to show variety of approaches in batching. Why repeat already posted script? May I draw your attention to batch (tag) documentation project? It does need attention of dedicated experts. User Documentation dashboard provides bird view on current activities and access to Edit Approval tools. – sambul35 Aug 02 '16 at 22:55