So basically I was working on my Terminal I am creating in batch and this strange error pops up for a second and then the window closes:
"Goto was unexpected at this time"
I have no idea what's going on. Here's my code:
#ECHO off
set codename=Nature
echo Windows Bat Terminal
echo Codename "%codename%"
:terminal
set /p terminalcommand=Command:
if %terminalcommand%==help goto help
if %terminalcommand%==clr goto clear
if %terminalcommand%==exit goto exit
if %terminalcommand%==color goto color
if %terminalcommand%==time goto timedate
echo.
echo Bad command!
:terminal1
goto terminal`
To recreate simply run this in CMD.
You haven't told us what entry you made to generate this behaviour. The standard cure is to quote each side if the if comparison (if /i "%terminalcommand%"=="time" goto ... (the /i make the comparison case-insensitive)) because if you simply press enter then the command is resolved to "if ==time goto ..." and cmd will see goto where it expects a comparison operator like ==, hence the response. If you run this batch from the command prompt, the window won't close and you'll be able to see these messages better
Related
I'm trying to make a batch script that behave almost like a Linux command in terms of arguments. Here is the idea of the script.
When I run the script with the scenarios described in the code it seems to work fine. The problem that I have is coming when I tried to test the program with wrong parameters. For the 1st parameter being either -manual or -automat and the 2nd parameter being wrong the behave is normal, the program prints "Invalid Argument".
The problem that I encounter is when the 1st argument is not -manual or -automat. In this case I get the error: goto was unexpected at this time.
Does any1 have any idea why this is happening and how can I solve the problem?
#echo off
IF %1!==! goto Result0
IF %1==-manual IF %2!==! goto Result1_manual
IF %1==-automat IF %2!==! goto Result1_auto
IF %1==-manual IF %2==1 goto Result2_manual
IF %1==-manual IF %2==2 goto Result3_manual
IF %1==-automat IF %2==1 goto Result2_auto
IF %1==-automat IF %2==2 goto Result3_auto
:done
echo "Invalid argument"
pause
cmd /k
:Result0
echo "Result0"
pause
cmd /k
:Result1_manual
echo "Result1_manual"
pause
cmd /k
:Result2_manual
echo "Result2_manual"
pause
cmd /k
:Result3_manual
echo "Result3_manual"
pause
cmd /k
:Result1_auto
echo "Result1_auto"
pause
cmd /k
:Result2_auto
echo "Result2_auto"
pause
cmd /k
:Result3_auto
echo "Result3_auto"
pause
cmd /k
If "%1"=="-manual" goto Result1_manual
If parameters might be missing enclose with another character. If %1 in blank and you don't
If ==-manual goto Result1_manual
an illegal syntax, and if you do
If ""=="-manual" goto Result1_manual
a legal syntax that resolves to false.
IF %2!==!
will only be true if %2 is blank. If that is your intention don't use the quote character. It sometimes has special meaning.
I have this question about why this choice command won't work. I've looked on this site and compared all my scripting and I just can't figure out why it won't work
http://www.computerhope.com/issues/ch001674.htm
#ECHO OFF
:START
echo 1 to quit or 2 to print hello and go back to this screen
CHOICE /C:12 /N
IF ERRORLEVEL ==1 GOTO QUIT
IF ERRORLEVEL ==2 GOTO HELLO
GOTO :START
:QUIT
EXIT
:HELLO
ECHO hello
GOTO :END
:END
I've made a couple of changes and removed unnecessary code.
#ECHO OFF
:START
CLS
ECHO=1 to quit or 2 to print hello and go back to this screen
CHOICE /C 12 /N
IF ERRORLEVEL 2 (CALL :HELLO & GOTO START)
EXIT /B
:HELLO
ECHO=hello
TIMEOUT 2 1>NUL
Simpler:
#ECHO OFF
:START
echo 1 to quit or 2 to print hello and go back to this screen
CHOICE /C 12 /N
GOTO OPTION-%ERRORLEVEL%
:OPTION-1 Quit
EXIT
:OPTION-2 Hello
ECHO hello
GOTO START
Testing on the errorlevel is done wrong.
There are two possibilities:
#ECHO OFF
:BEGIN
ECHO 1 to quit or 2 to print hello and go back to this screen
CHOICE /C:12 /N
IF ERRORLEVEL 2 GOTO HELLO
IF ERRORLEVEL 1 EXIT /B
GOTO BEGIN
:HELLO
ECHO hello
GOTO BEGIN
For full details see the chapter about CHOICE in my answer on: How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
The batch user must press either 1 or 2 as otherwise the batch execution is not continued. So testing for the exit code can be done from highest to lowest with:
if errorlevel X ...
That means IF the exit code assigned to the dynamic variable errorlevel is greater OR equal X THEN execute the command (or command block).
The advantage of using this syntax is that it even works in a command block without the need to use delayed variable expansion.
The second possibility is:
#ECHO OFF
:BEGIN
ECHO 1 to quit or 2 to print hello and go back to this screen
CHOICE /C:12 /N
IF %ERRORLEVEL% == 1 EXIT /B
IF %ERRORLEVEL% == 2 GOTO HELLO
GOTO BEGIN
:HELLO
ECHO hello
GOTO BEGIN
By explicitly referencing the dynamic variable ERRORLEVEL, here with expansion before IF evaluates the condition, the order of the errorlevel checks does not matter anymore.
The disadvantage of this method is the need of using delayed expansion if CHOICE and the errorlevel evaluating conditions are within a command block defined with ( ... ).
Run in a command prompt window if /? and set /? for help about right usage of the commands IF and SET respectively get information about delayed variable expansion.
It is possible to use START as label, but it is not advisable to do so because of START is an internal command of Windows command processor. You get troubles on finding START meaning the label and START meaning the command when your batch file will use ever also the command START. BEGIN is used as label for that reason.
It is also advisable to use command EXIT always with parameter /B at least during developing a batch file to exit only the batch processing, but do not completely exit the running command process independent on calling hierarchy and option used on starting cmd.exe.
It is much easier to debug a batch file by running it from within a command prompt window (cmd.exe started with option /K to keep console window open) instead of double clicking on the batch file (cmd.exe started with option /C to close on batch execution finished) on using exit /B instead of just exit as the command prompt window keeps open. Run in a command prompt window cmd /? for details about the options of the Windows Command Processor.
GOTO BEGIN after the two errorlevel evaluations is only executed on user pressing Ctrl+C or Ctrl+Break on this prompt and presses on prompt output by cmd to terminate the batch job the key N. That results in an exit of CHOICE with exit code 0.
It would be better to use %SystemRoot%\System32\choice.exe instead of just CHOICE if the batch file is for Windows Vista or Windows Server 2003 or newer Windows versions with support of Windows command CHOICE.
This code is part of a chat program that I am currently working on. The 'else' part of my program is the one that doesn't work. The program quits instead of going to :home
:join
cls
if not exist "C:/Users/Public/room.cmd" (
echo No room has been found.
echo.
set /p choiceretry=Do you want to retry? y/n
if "%choiceretry%"=="y" goto join
if "%choiceretry%"=="n" goto home
) else (
cls
"C:/Users/Public/room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
echo %roomjoined%
goto home
)
:home
echo this finally works
pause
I have tried changing the code several times starting from 'echo Joining'
Anyone know why cmd quits?...
:) :) :)
Thanks in advance
The problem is the way you run room.cmd; you must use call to return from it:
call "C:/Users/Public/room.cmd"
Otherwise, execution will not return from room.cmd to the original batch file that ran it.
Hint: Consider to use choice instead of set /P for Y/N decisions.
Firstly, please don't left justify your code blocks. It's much easier to read code that's properly indented.
Secondly, when retrieving values within a code block, you need delayed expansion. See setlocal /? in a cmd prompt for more information. This is the reason for the unexpected behavior. Your variables retrieved within the same parenthetical code block in which they were set won't contain the values you expect unless you retrieve them with delayed expansion syntax. As an alternative, you could use the choice command and if errorlevel, which would result in a bit nicer user experience I think.
Thirdly, when testing user input, you should use the /i switch in your if statements for case-insensitivity. This isn't relevant if using choice / if errorlevel though.
Fourthly, Windows paths use backslashes, not forward slashes.
I'd fix it this way:
#echo off
setlocal
:join
cls
if errorlevel 1 set /P "=Retrying... "<NUL
if not exist "C:\Users\Public\room.cmd" (
echo No room has been found.
echo.
choice /c yn /n /m "Do you want to retry? [y/n] "
if errorlevel 2 goto home
goto join
) else (
"C:\Users\Public\room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
)
:home
echo this finally works
pause
I'm really new in this forum so I hope to respect all your rules, if not please forgive me!
I've just started studying something about batch files and I'm trying to execute a simple program from batch passing a parameter (the last aim is to submit a SAS program passing a date parameter).
Is it possible to activate a sort of list where I can choose some between pre-defined parameters?
--> This is the real aim of my work
I'm trying to "play" with this code:
#echo off
title Setting up execution period
echo Insert your date in the format GGMMMAAAA (es: '31DEC2003'D).
SET /p data_par=Insert the date to filter datas:
SET first_byte=%data_par:~1,1%
if "%first_byte%"=="" (
GOTO tag1
) else (
GOTO tag2
)
:tag1
msg * Missing value
:tag2
msg * Well done!
pause
I've tried in a lot of ways but it looks like the IF statement is not executed, I don't know where am I wrong.
Another question: why the prompt closes after i press "Enter" (afte the set/p command is executed)?
--> this has been resolved putting the "pause" command at the end of the script.
Thank you all for the attention,
Best regards!
Squotty
Put a pause at the end of your code to see the errormessages.
correct syntax for if when using else is:
if "a"=="b" (dosomething) else (dosemethingelse)
You can write it in several lines, but there are rules, where to set the paratheses:
if "a"=="b" (
echo this is code for something
rem more lines possible
) else (
echo this is code for something else
rem more lines possible
)
The first ( has to be on the same line than if.
) else ( have to be on one line.
If you press just enter with set /p, the variable remains unchanged (propably empty), so your code will go on with the code and hits the line else. Here it will tell you "else is not recognized as a command..."
at your tagx you should tell batch, where to stop execution. Use goto :eof to stop execution or goto somewhere to continue somewhere else. If you don't, it will just continue with the next lines.
Example:
:tag1
msg * Missing value
goto :eof
:tag2
msg * Well done!
goto :continue
pause
:continue
REM go on with the program...
(note: the pause will never be reached. I let it there to show you, how things work)
EDIT instead of just checking for some input you can check for the correct format:
echo %data_par%|findstr /r "[0-3][0-9][A-Z][A-Z][A-Z][1-2]0[0-9][0-9]">nul && (
echo correct format
goto continue
) || (
echo wrong format
goto startover
)
It's not bullet proof (eg. 38ABC2019 would be considered "correct"), but at least it checks for the correct format (e.g. 15.12.2019 or 12/15/2014 would be "not correct")
#ECHO OFF
SETLOCAL
SET "item1=date1"
SET "item2=date2"
SET "item3=date3"
SET "item4=date4"
FOR /l %%a IN (1,1,4) DO CALL ECHO(%%a. %%item%%a%%
ECHO(U. User-specified
choice /c 1234u
CALL SET selection=%%item%errorlevel%%%
IF NOT DEFINED selection (
SET /p selection="Your date-selection ? "
)
IF NOT DEFINED selection ECHO No selection made&GOTO :EOF
ECHO selection is %selection%
GOTO :EOF
This code may be of assistance.
It's normal to develop batch code using a batch window. Simply set up a shortcut to command prompt (Start>Programs>Accessories) which would allow you to run the script over and over and retain the results on-screen without using 'pause'. Editing can be accomplished by using notepad batchfilename.bat from the prompt (if you are using notepad for an editor - if using something better, then substitute that program's name). You can exit from the batch window by executing an exit command.
You can also get help on batch commands by using commandname /? - it's often cryptic and there are plenty of quirks. Extensive help available here on SO.
I have a few things set up in a batch game. Instead of going where it is supposed to when the sure enters an option and hits "Enter" it goes to the next thing that starts with a : (I don't know what it is called).
Instead of it going to "Youtube" when the user types "Y".
:visitoption
echo Would you like to visit the RST Garry's mod gaming community website?
set /p option=Y or N:
if %option%==Y start chrome (Censored link)
if %option%==N cls goto :youtube
if %option%==y start chrome (Censored link)
if %option%==n cls goto :youtube
:version
cls
#echo off
echo.
echo[
#echo off
echo.
echo[
echo --Version--
echo Lightup Demo
#echo off
echo.
echo[
#echo off
echo.
echo[
#echo off
echo.
echo[
pause
goto :versionwhite
:youtube
echo Would you like to visit the Creator's Youtube channel?
echo Gameplay commentarys and such.
set /p option=Y or N:
if %option%==Y start chrome (Censored link)
if %option%==N goto :Beginning
if %option%==y start chrome (Censored link)
if %option%==n goto :Beginning
Essentially you were missing a command separator after the CLS but I've made some other changes such as /i case insensitive comparing and made the checking routines more robust to spaces or no input.
:visitoption
echo Would you like to visit the RST Garry's mod gaming community website?
set /p option=Y or N:
if /i "%option%"=="Y" start "" chrome "(Censored link)"
if /i "%option%"=="N" cls & goto :youtube
goto :visitoption
The "thing" is called a label
Since you have no control over what the user types, you should use
if "%option%"=="Y" start chrome (Censored link)
that is, quote both sides of the comparison (this is not bullet-proof, but serves adequately where the user is not deliberately trying to break your system.)
Adding the /i switch to the if will make the comparison case-insensitive.
if defined option set "option=%option:~0,1%"
will set option to just the first character.
Note that if the user replies simply Enter then the value of the variable remains unchanged. You can use this characteristic to your advantage
set "option=defaultvalue"
set /p option=Y or N:
will set option to defaultvalue if the user replies simply Enter.
start will start a process independently. The batch simply carries on to the next statement. You are probably beter off using start "window title for this instance" ... - it's a quirk of start that the first "quoted parameter" is used as the window title where you may be expecting it to be used as a parameter.
To concatenate a series of commands in a single line, you need to separate the individual commands with an ampersand &
Once you've turned echo off once, you don't need to do it again (unless you execute echo on, which you can do during debugging to show the program flow.) The leading # means don't echo this command - without it, the initial ECHO OFF would be reproduced.
You can use call :label to execute a subroutine that starts at :label in this batch file. If you use call label then the "subroutine" executed is the executable label. This is a very important distinction.
For this reason, I eschew the use of goto :label - although it works - because the colon is not necessary and for congruence between the goto and call commands.
The one exception to this omit-the-colons approach is where the colon actually does have an effect - goto :eof very specifically means 'goto the physical end of this batch file' - the label :eof is understood by cmd to have that meaning, and should not be defined in the batch.
You've set it so that it goes to youtube when the user presses n, not when the user enters y like you said your trying to in the question:
if %option%==N cls goto :youtube
Please try seeing what the cod eyour using is doing before you post a question on it.
And SO has one of the worlds easiest CodeSlabing systems. HOW BLOODY HARD IS IT TO PRESS SPACE 4 TIMES OR HIGHLIGHT AND PRESS THE "Code Sample" BUTTON?
Mona.