Exit with errorlevel from windows batch - windows

In my batch file I have a function where use this command to connect to a remote host:
net use %alias%: \\%host%\%root%$ %usrPwd% /USER:%usrName% >> %logfile% 2>&1 || ( call :exitIfError ERROR)
I created this function:
:exitIfError
setlocal
(set txt=%~1)
if not ERRORLEVEL 0 ( echo %txt% && exit /B %errorlevel%)
endlocal
goto :eof
If I enter an incorrect password is generating the error, but doesn't finish with error and the value of %errolevel% is 0
instead of 2. Suggestions?

:exitIfError
if ERRORLEVEL 1 (echo %~1& exit /B %errorlevel%)
exit /b 0
There appears to be no reason to set txt

Related

windows batch errorlevel with if

In the below script even if errorlevel is 0, Its going to if condition "if errorlevel 1"
#echo off
if exist servers.txt goto :continue
echo servers.txt file is missing
exit
:continue
set instance=%username:~2%
setlocal enabledelayedexpansion
for /f "delims=" %%i in (servers.txt) do (
pushd \\%%i\D$\%instance%\Hyperion\oracle_common 2>nul
if not errorlevel 1 (
echo %%i
echo **********************************
set ORACLE_HOME=!CD!
echo ORACLE_HOME is !ORACLE_HOME!
D:
FOR /D /r D:\%instance%\Hyperion %%a in ("jdk160_*") DO CD %%a
set JAVA_HOME=!CD!
echo JAVA_HOME is !JAVA_HOME!
echo D:\%instance%\Hyperion\oracle_common\oui\bin\setup.exe -jreLoc !JAVA_HOME! -silent -attachHome ORACLE_HOME=!ORACLE_HOME! ORACLE_HOME_NAME="REMOTE_EPM"
D:\%instance%\Hyperion\oracle_common\oui\bin\setup.exe -jreLoc !JAVA_HOME! -silent -attachHome ORACLE_HOME=!ORACLE_HOME! ORACLE_HOME_NAME=REMOTE_EPM
echo error code is:%errorlevel%
if errorlevel 2 (
echo unable to attach remote server %%i ORACLE_HOME to inventory
pause
exit
)
cd D:\%instance%\Hyperion\oracle_common\OPatch
if errorlevel 1 (
echo Failed to locate OPatch location D:\%instance%\Hyperion\oracle_common\OPatch
pause
exit
)
echo current: !CD!
opatch.bat lsinv | find "applied on"
D:\%instance%\Hyperion\oracle_common\oui\bin\setup.exe -jreLoc !JAVA_HOME! -silent -detachHome ORACLE_HOME=!ORACLE_HOME! ORACLE_HOME_NAME="REMOTE_EPM"
if errorlevel 1 (
echo Error: unable to detach remote server %%i ORACLE_HOME from inventory
pause
exit
)
popd
pause
) else (
echo ORACLE_HOME is Not found: \\%%~i\D$\%instance%\Hyperion\oracle_common
)
pause
)
endlocal
Output is:
vmhodwbrep9.oracleoutsourcing.com
**********************************
ORACLE_HOME is Y:\pwbre7\Hyperion\oracle_common
JAVA_HOME is D:\pwbre7\Hyperion\jdk160_35
D:\pwbre7\Hyperion\oracle_common\oui\bin\setup.exe -jreLoc D:\pwbre7\Hyperion\jdk160_35 -silent -attachHome ORACLE_HOME=Y:\pwbre7\Hyperion\oracle_common ORACLE_HOME_NAME="REMOTE_EP
M"
error code is:0
unable to attach remote server vmhodwbrep9.oracleoutsourcing.com ORACLE_HOME to inventory
Press any key to continue . . .
Unless command extensions are enabled, you cannot easily access ERRORLEVEL in an echo statement.
Also keep in mind that you must check your conditions in reverse because...:
IF ERRORLEVEL 1 ....
checks to see if ERRORLEVEL is greater than or equal to one. So, a series of tests would be:
IF ERRORLEVEL 5 ....
IF ERRORLEVEL 4 ....
IF ERRORLEVEL 3 ....
IF ERRORLEVEL 2 ....
IF ERRORLEVEL 1 ....
Finally, recognize that in an IF statement, %errorlevel% is *not* the same asERRORLEVEL`. You don't try it this way, but another answer does.
change
echo error code is:%errorlevel%
if errorlevel 2 (
to
call echo error code is:%%errorlevel%%
if errorlevel 2 (
OR, preferably since you have invoked delayedexpansion,
echo error code is:!errorlevel!
if errorlevel 2 (
With your current code, the entirity from
if not errorlevel 1 (
to the single ) before the endlocal line is one block statement.
Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).
Hence, since the block starts with
if not errorlevel 1 (
then %errorlevel% will be replaced by the value of errorlevel at the time the if is encountered, that is 0, so your echo will be replaced by echo error code is:0
Two common ways to overcome this are 1) to use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var or 2) to call a subroutine to perform further processing using the changed values.
Note therefore the use of CALL ECHO %%var%% which displays the changed value of var. CALL ECHO %%errorlevel%% displays, but sadly then RESETS errorlevel.
note that last statement
CALL ECHO %%errorlevel%%` displays, but sadly then RESETS errorlevel.
So your errorlevel would now be displayed correctly, but would be reset to 0 by the call.

Checking error level while building with sbt

I want to write a windows .cmd script that publishing all project modules into local repository. But I want to stop at first error that may be occur. I'm checking %ERRORLEVEL% but it's always equals to 0 even if sbt publish-local command fails with some error.
#echo on
#setlocal enabledelayedexpansions
set modules=^
sbt-common^
common^
for %%A in (%modules%) do (
echo ======================================
echo = PUBLISHING %%A =
echo ======================================
cd %%A
call sbt publish-local
echo %ERRORLEVEL% :: <- Always = 0
if ERRORLEVEL 1 goto error
)
:error
#endlocal
exit /B 1
Any help will be appreciated.
Try this:
#echo on
#setlocal EnableDelayedExpansion
set modules=^
sbt-common^
common^
for %%A in (%modules%) do (
echo ======================================
echo = PUBLISHING %%A =
echo ======================================
cd %%A
call sbt publish-local
echo !ERRORLEVEL!
if !ERRORLEVEL! geq 1 goto error
)
:error
#endlocal
exit /B 1
Note that EnableDelayedExpansion should not have a following s, and you should use ! instead of % inside parenthesis in batch.

How execute a command in batch-file if errorlevel is not zero?

I created a simple batch file which would enable me to connect to the internet.
I made it this way- If the connection is successful a message is displayed stating "connection successful" using VBscript and display a message stating "connection failure" if the connection is not established. I made this using if-else statements and errorlevel command, but I am not able to display the failure message using 'errorlevel == 1' command.I mean that if there was an error in the connection process the success message is displayed instead of failure message.
Here's the code in my batch file.
rasdial "TATA PHOTON+" internet
#echo off
if ERRORLEVEL == 0 (echo MSGBOX "Connection successfully established to TATA PHOTON+" > %temp%\TEMPmessage.vbs
call %temp%\TEMPmessage.vbs
del %temp%\TEMPmessage.vbs /f /q)
else if ERRORLEVEL == 1 (echo MSGBOX "ERROR: Unable to establish connection" > %temp%\TEMPmessage.vbs
call %temp%\TEMPmessage.vbs
del %temp%\TEMPmessage.vbs /f /q
)
The line
if errorlevel == 0 do-something
is not valid syntax. Based on some quick tests, it would appear that the command processor is reinterpreting it as
if errorlevel 0 do-something
which means "if errorlevel is at least 0 do something".
Instead, I recommend
if %ERRORLEVEL% EQU 0 do-something
Using the percent-signs version allows you to test for equality and also correctly handles the case where the return value is negative.
if errorlevel == 1 compares the string errorlevel to the string 1 and for some reason finds they don't match.
You need either
if %errorlevel% == 1 dosomething
or
if errorlevel 1 dosomething
Where the second method will execute dosomething if errorlevel is 1 or is greater than 1
consequently, if errorlevel 0 dosomething will always dosomething.(but there are ways of setting `errorlevel to a negative amount. This is not normally encountered)
Try something like that :
rasdial "TATA PHOTON+" internet
#echo off
IF %ERRORLEVEL% EQU 0 (
Goto :sucess
) else (
GoTo :Fail
)
::****************************************************************************************
:sucess
(echo MSGBOX "Connection successfully established to TATA PHOTON+",VbInformation,"Connection successfully established to TATA PHOTON+" > %temp%\TEMPmessage.vbs
call %temp%\TEMPmessage.vbs
del %temp%\TEMPmessage.vbs /f /q
)
Exit /b
::****************************************************************************************
:Fail
(echo MSGBOX "ERROR: Unable to establish connection",vbCritical,"ERROR: Unable to establish connection" > %temp%\TEMPmessage.vbs
call %temp%\TEMPmessage.vbs
del %temp%\TEMPmessage.vbs /f /q
)
Exit /b
::****************************************************************************************

Strange behavior of batch file

I have two cmd files.
child.cmd:
#echo off
exit 1
parent.cmd:
#echo off
cmd /C child.cmd
if %errorlevel% EQU 0 (
echo OK
) else (
echo ERROR
)
If to run parent.cmd, then ERROR will be printed.
But if a little change parent.cmd, then OK will be printed:
#echo off
if "YES" EQU "YES" (
cmd /C child.cmd
if %errorlevel% EQU 0 (
echo OK
) else (
echo ERROR
)
)
Why OK is printed in the second example?
inside a code block you need delayed expansion to access %variables%:
#echo off &setlocal enabledelayedexpansion
if !errorlevel! EQU 0 (
You can also use this syntax without delayed expansion:
if errorlevel 1 if not errorlevel 2 ( echo error )

Windows Batch For Loop: having trouble with the following code

set checker=0
for %%a in (%namelist%) do (
:startLoop
findstr "completed" %%a_Logs.txt
IF ERRORLEVEL 1 (
IF %checker%==120 (
set checker=0
goto endLoop
)
set /a checker=%checker%+1
#ping 127.0.0.1 -n 1 -w 1000 > nul
findstr "ERROR" %%a_Logs.txt
IF ERRORLEVEL 1 (
echo Waiting 1 second before rechecking (Max 2 mins)
echo time elapsed %checker% seconds
echo.
goto startLoop
)
findstr "ERROR" %%a_Logs.txt
IF NOT ERRORLEVEL 1 (
echo ERROR: %%a Error found
goto endLoop
)
)
findstr "completed" %%a_Logs.txt
IF NOT ERRORLEVEL 1 (
echo %%a completed
)
:endLoop
)
The above piece of code is to do the following:
Parse the variable namelist(where the contents are separated by spaces)
Check if "completed" is present in the %%a_Logs.txt file
If it is present, then iteration over, If it is not, then check for the string "ERROR" in same file
If ERROR is present, then output ERROR MSG and end iteration
If ERROR is not found, keep rechecking for the next 120 seconds before ending iteration
I keep getting the following output
FINDSTR: Cannot open %a_Logs.txt
You are attempting to GOTO a label within a FOR loop - that simply doesn't work. The moment a FOR loop executes GOTO, the loop is terminated, and the FOR context is lost. So your %%a FOR variable is no longer defined. A similar issue happens with IF statements, as described at (Windows batch) Goto within if block behaves very strangely.
You also have a problem when you attempt to expand %checker% within the same parenthesized code block that sets the value. That expansion occurs at parse time, and the entire block is parsed at once. So the value you see will always be the value that existed before the block was entered. The solution is to enable delayed expansion and use !checker! instead of %checker%.
Personally, I would probably make significant changes to your code. But I believe the following minimal changes can make your code work, assuming there are no other bugs:
enable delayed expansion
Move your DO loop code to a routine outside of the loop, and then have the loop CALL that routine with %%a as a parameter. CALL does not break the loop.
Substitute %1 for %%a in the routine
Substitute exit /b for goto endLoop. Also put exit /b at end of the routine
Make sure the code does not fall into the routine when the FOR loop finishes. I used a GOTO after the FOR loop
Substitute !checker! for %checker%
EDIT -The ) in the ECHO statement must be escaped
Here is the modified code (untested)
setlocal enableDelayedExpansion
set checker=0
for %%a in (%namelist%) do call :startLoop %%a
goto continue
:startLoop
findstr "completed" %1_Logs.txt
IF ERRORLEVEL 1 (
IF !checker!==120 (
set checker=0
exit /b
)
set /a checker=checker+1
#ping 127.0.0.1 -n 1 -w 1000 > nul
findstr "ERROR" %1_Logs.txt
IF ERRORLEVEL 1 (
echo Waiting 1 second before rechecking (Max 2 mins^)
echo time elapsed !checker! seconds
echo.
goto startLoop
)
findstr "ERROR" %1_Logs.txt
IF NOT ERRORLEVEL 1 (
echo ERROR: %1 Error found
exit /b
)
)
findstr "completed" %1_Logs.txt
IF NOT ERRORLEVEL 1 (
echo %1 completed
)
exit /b
:continue
I think the labels inside your for loop are messing it up. I just tried it moving the contents of the loop into a separate "subroutine" and that gets rid of the error you mention.
Try this:
set checker=0
for %%a in (foo bar baz) do (
call :loop %%a
)
goto :eof
:loop
set basename=%1
:startLoop
findstr "completed" %basename%_Logs.txt
IF ERRORLEVEL 1 (
IF %checker%==120 (
set checker=0
goto endLoop
)
set /a checker=%checker%+1
#ping 127.0.0.1 -n 1 -w 1000 > nul
findstr "ERROR" %basename%_Logs.txt
IF ERRORLEVEL 1 (
echo Waiting 1 second before rechecking (Max 2 mins)
echo time elapsed %checker% seconds
echo.
goto startLoop
)
findstr "ERROR" %basename%_Logs.txt
IF NOT ERRORLEVEL 1 (
echo ERROR: %basename% Error found
goto endLoop
)
)
findstr "completed" %basename%_Logs.txt
IF NOT ERRORLEVEL 1 (
echo %basename% completed
)
:endLoop
goto :eof

Resources