I 'm trying to create a batch file as below.
#ECHO OFF
:Main
CALL :STEP_1
CALL :STEP_2
GOTO :EXIT
:STEP_1
REM some other logic here
IF %ERRORLEVEL% NEQ 0 (
GOTO :ERROR
)
GOTO :EOF
:STEP_2
REM step 2 logic
GOTO :EOF
:ERROR
EXIT /b 1
:EXIT
EXIT /b 0
What I'm expecting is that the error handling in :STEP_1 will exit from the whole batch file. However, what is happening is that it only exit from the content we created when we use CALL. :STEP_2 will still be called even if there is an error in :STEP_1.
My question is, is it possible to accomplish my requirement? To exit from the whole batch file instead of the :STEP_1 context, so :STEP_2 won't be called.
You can use the following (GOTO) 2>NUL combined with an exit, and that should do the job for you.
:ERROR
(goto) 2>nul & exit /b 1
Refer to this for more information.
Related
Below is a batch script that I have put together which copies the content of another folder and pastes it into a new folder that it creates called IC_Transfer.
#echo off
#break off
#title IC Transfer
setlocal EnableDelayedExpansion
if not exist "C:\Temp\IC_Transfer" (
md "C:\Temp\IC_Transfer"
ROBOCOPY /-y "Q:\Work\Temp\Dan" "C:\Temp\IC_Transfer" /mir
if "!errorlevel!" EQU "0" (
echo Transfer Successful! )
) else (
if exist "C:\Temp\IC_Transfer" (
echo Error Transferring File
echo File Already Exists
:Choice
set /P c=Would You Like To Overwrite[Y/N]?
if /I "%c%" EQU "Y" goto Overwrite
if /I "%c%" EQU "N" goto Stop
) )
:Overwrite
md "C:\Temp\IC_Transfer"
ROBOCOPY "Q:\Work\Temp\Dan" "C:\Temp\IC_Transfer" /mir
if "!errorlevel!" EQU "0" (
echo Transfer Successful )
goto End
:Stop
echo Transfer Cancelled
goto End
:End
pause
exit
pause
exit
The make directory and robocopy functions work as they should by purging the directory, re-creates it and pastes the contents. What I cannot get working is the choice command.
Regardless of whether I choose Y or N it overwrites the file contents.
I'm new to batch scripts so any help would be appreciated
#echo off
#break off
#title IC Transfer
setlocal
if not exist "C:\Temp\IC_Transfer" (
md "C:\Temp\IC_Transfer"
ROBOCOPY /-y "Q:\Work\Temp\Dan" "C:\Temp\IC_Transfer" /mir
if not errorlevel 1 (
echo Transfer Successful!
) else (
echo Error Transferring File
echo File Already Exists
call :Choice
)
)
exit /b
:Choice
setlocal
set "c="
set /P "c=Would You Like To Overwrite[Y/N]? "
if /I "%c%" == "Y" (
call :Overwrite
) else if /I "%c%" == "N" (
call :Stop
) else call :Stop
exit /b
:Overwrite
ROBOCOPY "Q:\Work\Temp\Dan" "C:\Temp\IC_Transfer" /mir
if not errorlevel 1 echo Transfer Successful
pause
exit /b
:Stop
echo Transfer Cancelled
pause
exit /b
To fix the issue, labels inside parenthese code blocks is a
bad idea and prone to error. So call the label instead.
I replaced the goto's with calls as :Choice will work with a call.
This makes :End obsolete.
You used delayed expansion for errorlevel, though you could just use
i.e. if not errorlevel 1 to check if integer value is less than 1.
Delayed expansion has been removed.
Labels within code blocks (parenthesised series of commands) cause problems (:choice) and are better regarded as illegal.
You have invoked delayedexpansion and recognised that errorlevel may change with the code block. Your set /p changes the variable c, but you are using the parse-time value of c (%c%) in your if statements, not the run-time value (!c!)
What happens should the user enter not-YN? Hint: See the choice command - choice /? from the prompt.
Since c is not set at the start of the code, "%c%" will evaluate to "" which is neither "Y" nor "N" so the ifs fail and the code will then proceed to the next statement (:overwrite)
Note that md will create a directory or generate an error message if it does not exist, hence
md directoryname 2>nul
should create the directory and suppress error messages (like 'directory already exists') obviating the test-for-existence gating the md.
I have a Script with different subroutines:
REM ---------------MAIN------------------------START----------------------------
call :SUB_GetStartTime
call :SUB_SettingVariables
call :SUB_CheckingParameters %*
call :SUB_Copy
call :SUB_GetEndTime
call :SUB_WriteLog
call :SUB_EndScreen
REM ---------------MAIN------------------------END------------------------------
At SUB_CheckingParameters I have this if query:
if "%~1"=="/help" (
GOTO SUB_HELP
)
If I pass the parameter /help it goes to my help window:
cls
ECHO ===================HELP==============
ECHO help text help text help text
ECHO =====================================
timeout /t 120
exit /b
after exit /b I want the script to end but it just goes to my next subroutine (SUB_Copy). Shouldnt the script end because I use GOTO SUB_Help and not call ?
Can someone help me and tell me what I am doing wrong?
I ususally handle this by passing back an errorlevel:
#Echo off
REM ---------------MAIN------------------------START----------------------------
call :SUB_GetStartTime
call :SUB_SettingVariables
call :SUB_CheckingParameters %* || Exit /b 1
call :SUB_Copy
call :SUB_GetEndTime
call :SUB_WriteLog
call :SUB_EndScreen
REM ---------------MAIN------------------------END------------------------------
Echo end of main
Pause
Goto :Eof
:SUB_CheckingParameters
if /I "%~1"=="/help" GOTO SUB_HELP
:SUB_GetStartTime
:SUB_SettingVariables
:SUB_Copy
:SUB_GetEndTime
:SUB_WriteLog
:SUB_EndScreen
Echo:We are in %~0 Args %*
Goto :Eof
:SUB_HELP
rem cls
ECHO ===================HELP==============
ECHO help text help text help text
ECHO =====================================
timeout /t 120
exit /b 1
My goal is to compare say the contents of one txt file to the contents of all text files on a specific folder, if ANY txt files match then do one set of processes if none match then do another set.
I've tried doing the below:
#echo off
:main
fc "C:\Users\degibson\Desktop\test\*.txt" "C:\Users\degibson\Desktop\test2\temp1.txt" > NUL
if errorlevel 1 goto error
:next
echo do some important task
pause
:error
echo do some other important task
pause
Problem - This only works if ALL the files matched temp1.txt contents.
Is there a better way to accomplish this task?
You can use the FOR command to iterate all text files in the directory. I would then suggest you use the CALL command instead of GOTO because CALL will return execution to the FOR command whereas the GOTO will break the FOR command execution. The execution returns to the FOR command by using the builtin :EOF label to end the current called process. You could also use EXIT /B.
#ECHO OFF
:main
FOR %%G IN (C:\Users\degibson\Desktop\test\*.txt) DO (
fc "%%G" "C:\Users\degibson\Desktop\test2\temp1.txt" >NUL
if errorlevel 1 (
CALL :error
) ELSE (
CALL :next
)
)
GOTO :EOF
:next
echo do some important task
pause
GOTO :EOF
:error
echo do some other important task
pause
GOTO :EOF
I have a problem.
set /p command=
if %command% == "display (i want the second part of the variable here)" echo (second part of the variable)
For example, i type:
display hello
I want it to simply:
echo hello
I want to use this for custom commands in my game.
Firstly, you can split the text on firstword|notfirstword with a for /f loop using "tokens=1*". See help for in a console window for full details.
Next, you could use attempt to call :label where :label is whatever the first word was. In essence, you're creating batch functions and letting the user choose which function is executed. If the function label doesn't exist, then errorlevel will be non-zero and you can handle appropriately using conditional execution. This makes it easy to expand your script without having to add an if /i statement for each choice or synonym you add. (It might be a good idea to hide the error message for attempting to call a non-existent label by redirecting 2>NUL.) Here's a full example:
#echo off & setlocal
:entry
set /P "command=Command? "
for /f "tokens=1*" %%I in ("%command%") do (
2>NUL call :%%I %%J || (
if errorlevel 1000 (exit /b 0) else call :unsupported %%I
)
goto :entry
)
:display
:echo
:say
:show
echo(%*
exit /b 0
:ping
ping %~1
exit /b 0
:exit
:quit
:bye
:die
echo OK, toodles.
exit /b 1000
:unsupported <command>
1>&2 echo %~1: unrecognized command
exit /b 0
Trying to create a batch file to make these tasks run faster.
Can someone please correct my errors or suggest a better way to write this script
Basically everytime I run it says "request timed out"
#echo off
color 0a
Title
:Beginning
set /p UserInput = What Would You Like To Start?
echo.
if %UserInput% == 1 goto :Windows Update
if not %UserInput% == "" goto :Exit
else goto :Exit
if %UserInput% == 2 goto :Group Policy Update
if not %UserInput% == "" goto :Exit
else goto :Exit
if %UserInput% == 5 goto :Favorites
if not %UserInput% == "" goto :Exit
else goto :Exit
if %UserInput% == 3 goto :Tools
if not %UserInput% == "" goto :Exit
else goto :Exit
if %UserInput% == 4 goto :Printer
if not %UserInput% == "" goto :Exit
else goto :Exit
:Windows Update
start C:\Windows\system32\wuapp.exe
pause
exit
:Group Policy Update
start gpupdate.exe
pause
exit
:Favorites
move %userprofile%\favorites\*.* G:\
pause
exit
:Tools
start \\NoneOFyourBusiness
pause
exit
:Printer
start iexplore.exe http://www.Google.com
pause
exit
:Exit
set /p beginning == Return To The Start?
echo.
echo Y=Yes or N=No
if %beginning% == "Y" goto :Beginning
if not %beginning% == "N" goto :Exit 2
:Exit 2
pause
exit**'
set /p UserInput = What Would You Like To Start?
Will apply the input string to a variable named UserInputSpace
Batch is sensitive to spaces on both sides of the = in a set (but not a set /a)
if not %UserInput% == "" goto :Exit
Because you have no control over the use's input, that may contain spaces and other character to which batch is sensitive.
use
if not "%UserInput%"=="" goto :Exit
Note that the two strings must be exactly equal. IF /i ... will make the test case-insensitive.
Note also that responding simply Enter to a set /p will leave the variable unchanged, it will not "set" it to an empty string. If you want that, use
set "var="
set /p var=
Also, to detect whether var has been set, use
if defined var
if "%UserInput%"=="1" goto :Windows Update
This is a fail-to-fail scenario. The real command executed will be
if "%UserInput%"=="1" goto Windows
The remaining text after the space-separator is documentation.
Not a good idea IMHO to use the colon in a goto. It works, but there is a difference with a CALL statement. CALL :something will execute an internal subroutine (ie subroutine in this batch file) named something, whereas CALL something without the colon will call an external executable. By analogy, GOTO should also not be used with a colon. The one exception is the documented special condition, GOTO :EOF where the colon is required. GOTO :EOF means 'go to the end of the physical batch file.The labelEOFneed not (indeed **should** not) be included in the batch.CMD` knows where it has to go...
So - fix those and it should work a lot better. Not sure what the error response you have is, but I'd suggest it's some utility you'd not expected to run getting tired of waiting for input.
Try this...
color 0a
Title Testing
REM Since exit is a keyword - changed to leave
:Begining
echo choose an option
choice /c 12345
rem set /p UserInput = What Would You Like To Start?
echo.
if %errorlevel% == 1 goto WindowsUpdate
if %errorlevel% == 2 goto GroupPolicyUpdate
if %errorlevel% EQU 5 goto Favorites
if %errorlevel% EQU 3 goto Tools
if %errorlevel% EQU 4 goto Printer
:WindowsUpdate
start C:\Windows\system32\wuapp.exe
pause
goto leave
:GroupPolicyUpdate
start gpupdate.exe
pause
goto leave
:Favorites
move %userprofile%\favorites\*.* G:\
pause
goto leave
:Tools
start \\NoneOFyourBusiness
pause
goto leave
:Printer
start iexplore.exe http://www.Google.com
pause
goto leave
:leave
echo leave the script?
choice /c YN
if %errorlevel% NEQ 1 goto Begining
if %errorlevel% EQU 1 exit
** #echo off
color 0a
Title
:Beginning
set UserInput=Error
set /p UserInput=What Would You Like To Start?
echo.
if "%UserInput%"=="WU" goto Windows Update
if not "%UserInput%"=="" goto Exit
if "%UserInput%"=="GPU" goto Group Policy Update
if not "%UserInput%"=="" goto Exit
if "%UserInput%"=="Fav" goto Favorites
if not "%UserInput%"=="" goto Exit
if "%UserInput%"=="T" goto Tools
if not "%UserInput%"=="" goto Exit
if "%UserInput%"=="P" goto Printer
if not "%UserInput%"=="" goto Exit
:Windows Update
start C:\Windows\system32\wuapp.exe
goto exit
:Group Policy Update
start gpupdate.exe
goto exit
:Favorites
move %userprofile%\favorites\*.* G:\
goto exit
:Tools
start \\T
goto exit
:Printer
start iexplore.exe http://Google.com/
:Exit
set Beginning==Error
set /p Beginning==Return To The Start?
echo.
echo y=Yes or n=No
if "%Beginning%"=="y" call :Beginning
if not "%Beginning%"=="n" goto Exit 2
:Exit 2
pause
exit**