I'm using a batch script to automatically run some simulations and record data. However, because this is for the purposes of testing, I routinely get error messages that pop up from the batch script because there was a bug in the simulation software. I'd like to add in a couple of different things into the script, both of which I'm extremely fuzzy on the implementation, hence my question.
1st, I'd like to put in a script that will cause an entry to become null when an error message pops up.
I have a loop that looks like this
for /f "delims=_" %%J IN ('forfiles /p "%%F" /m *.ext/c "cmd /c echo @path"') DO (
set start=!time!
start "PROGRAM" /D "c:\Path\to\the\PROGRAM" /Wait program -r %%J
rem This loop uses a regular expression to find the database name from the .ext file
rem and sets it to a variable.
for /f "tokens=3 delims=<>" %%a in ('findstr "<Name>ABCDir" "%%~fJ"') do set name=%%a
set end=!time!
rem The following two loops convert start time and end time to centiseconds.
rem The time variable will be converted to minutes inside a sql query so that floats are possible.
for /F "tokens=1-4 delims=:.," %%a in ("!start!") do (
set /a "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
for /F "tokens=1-4 delims=:.," %%a in ("!end!") do (
set /a "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
rem Calculate the elapsed time by subtracting values
set /A elapsed=end-start
sqlcmd -S SERVER -d DATABASE -v Var1 = "!name!" Var2 = "%variable2%" Var3 = !elapsed! Var4 = %variable4% -i "\\path\to\the\query\Insert.sql"
)
So I'd like so that everytime an error message pops up, the script starts running the next file and changes the !elapsed!
variable to null
.
But I would like to also add in a script that will echo what the errorlevel is that pops up. I've seen one method of doing this is like this:
@ECHO OFF
IF ERRORLEVEL 1 SET ERRORLEV=1
IF ERRORLEVEL 2 SET ERRORLEV=2
IF ERRORLEVEL 3 SET ERRORLEV=3
IF ERRORLEVEL 4 SET ERRORLEV=4
•
•
•
IF ERRORLEVEL 254 SET ERRORLEV=254
IF ERRORLEVEL 255 SET ERRORLEV=255
ECHO ERRORLEVEL = %ERRORLEV%
but there seems like there should be a more efficient way to do this like with a loop that counts up errorlevel i set errorlev = i where i=0 and goes to n.
I really appreciate any insight you guys can offer.
Firstly, if all you want to do is conditional execution based on the zero or non-zero exit code of "PROGRAM", use &&
and ||
to designate code blocks for success or fail like this:
for /f "delims=_" %%J IN ('forfiles /p "%%F" /m *.ext/c "cmd /c echo @path"') DO (
set start=!time!
start "PROGRAM" /D "c:\Path\to\the\PROGRAM" /Wait program -r %%J && (
rem program exited status 0 (success)
rem This loop uses a regular expression to find the database name from the .ext file
rem and sets it to a variable.
for /f "tokens=3 delims=<>" %%a in ('findstr "<Name>ABCDir" "%%~fJ"') do set name=%%a
set end=!time!
rem The following two loops convert start time and end time to centiseconds.
rem The time variable will be converted to minutes inside a sql query so that floats are possible.
for /F "tokens=1-4 delims=:.," %%a in ("!start!") do (
set /a "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
for /F "tokens=1-4 delims=:.," %%a in ("!end!") do (
set /a "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100"
)
rem Calculate the elapsed time by subtracting values
set /A elapsed=end-start
sqlcmd -S SERVER -d DATABASE -v Var1 = "!name!" Var2 = "%variable2%" Var3 = !elapsed! Var4 = %variable4% -i "\\path\to\the\query\Insert.sql"
) || (
rem Program exited status non-zero (fail)
set "elapsed="
rem Continue looping to next result of forfiles
)
)
See this page for more on this sort of conditional execution.
Regarding echoing the errorlevel, it's already in %ERRORLEVEL%
. You don't have to use a series of if ERRORLEVEL
statements to set it. Try this on the command-line:
cmd /c exit /b 5
echo %ERRORLEVEL%
It should echo 5.
One other note, although I'm not sure you still need it knowing what you know now, if ERRORLEVEL N
checks if %ERRORLEVEL%
is greater than or equal to N. So if ERRORLEVEL 5
would return true if %ERRORLEVEL%
is 8. For this reason, series of if ERRORLEVEL
commands are usually written in descending order.
if ERRORLEVEL 3 (
do stuff
) else if ERRORLEVEL 2 (
do something else
) else etc...