Page 1 of 1

LABEL Being Processed without GOTO or CALL

Posted: 22 Jun 2018 17:50
by aecnrn
I have small batch that will try to map a migration folder on remote computers. My :ERRORMAPDRIVE label is being processed even it was not called or told to goto. I tested with 1 valid IP, it was successfully mapped, but the batch somehow still process the label making my error log is inaccurate.

Can someone tell me what is wrong with my code? The label is not supposed to be processed as a normal batch unless I specify goto in the first if statement, correct?

Update:

Full batch uploaded, basically i want the batch to:

1. Map E:\Migration on a remote machine, if there's no migration in E:\, try mapping D:\Migration.
2. Check if files exist
3. Direct file check messages to Log.txt and error messages to Error.txt

Problem:
1. When both map drive attempt fails, batch continues to check if files exist
2. When goto is used, the batch logs the error message in error.txt even when the first map drive is successful.

Code: Select all

REM Start Loop to read IPs
:START
for /F "tokens=1" %%B in (.\IPList.txt) do call :MAPDRIVE %%B
REM End Loop to read IPs

REM Start Complete Task
echo.
REM net use %Drive% /del 2>nul
echo File Check Complete!!
echo %date:~-10%%time:~0,8%:*** FileCheck Complete!! >> Logs.txt
goto :eof
REM End Complete Task

REM Start Delete if Exist
:MAPDRIVE
if exist %drive% (
	echo.
	echo %drive% drive exist on this computer, deleting %drive% drive
	echo. 
	net use %drive% /del
)
REM End Delete if Exist

REM Start On Screen Display Message
echo *** Mapping %RDriveE%: drive on remote machine %1 ***
echo %date:~-10%%time:~0,8%:*** Mapping %RDriveE% drive on remote machine %1 *** >> Logs.txt
REM End On Screen Display Message

REM Start MAP Network Drive
net use L: \\%1\%RDriveE%$\%MG% /u:%1\%username% %pwd% >nul 2>&1
	if errorlevel 1 (
	GOTO RETRY
	) else (
	echo Successfully Mapped Drive %RDriveE%: On %1
)

:RETRY	
echo.
echo %MG% folder doesn't exist in drive %RDriveE%: of the remote machine
echo Finding %MG% folder in the drive %RDdriveD%: instead...
echo.
net use L: \\%1\%RDdriveD%$\%MG% /u:%1\%username% %pwd% >nul 2>&1
		if errorlevel 1 (
		GOTO ERRORMAPDRIVE
		) Else (
		echo Successfully Mapped Drive %RDdriveD% On %1
)

REM End of Map Network Drive

REM For Loop
echo *** Checking files on %1 ***
echo *** Checking files on %1 *** >> Logs.txt
echo.
echo. >> Logs.txt

REM Start Check Migration Folder
for %%A in ("%gho%" "%GSha%" "%PrepPCI%" "%FileCopy%") Do (
	timeout /t 1 >nul
    if exist "%Drive%\%%~A" (
        echo %%~A exists in the %MG% Folder
		echo %date:~-10%%time:~0,8%:%%~A exists in the %MG% Folder >> Logs.txt
    ) else (
        echo %%~A does not exists in the %MG% Folder 
		echo %date:~-10%%time:~0,8%:%%~A does not exists in the %MG% Folder >> Logs.txt
    )
)
REM End Check Migration Folder

REM Start Check PCI Folder
for %%A in ("%IM%" "%ES%" "%PAS%") Do (
	timeout /t 1 >nul
    if exist "%Drive%\%PCI%\%%~A" (
        echo %%~A exists in the %PCI% Folder
		echo %date:~-10%%time:~0,8%:%%~A exists in the %PCI% Folder >> Logs.txt
    ) else (
        echo %%~A does not exists in the %PCI% Folder 
		echo %date:~-10%%time:~0,8%:%%~A does not exists in the %PCI% Folder >> Logs.txt
    )
)
REM End Check PCI Folder

REM Start Check POST Folder
for %%A in ("%NLM%" "%RSS%" "%Clean%" "%PCIS%" "%ESET%") Do (
	timeout /t 1 >nul
    if exist "%Drive%\%POS%\%%~A" (
        echo %%~A exists in the %POS% Folder
		echo %date:~-10%%time:~0,8%:%%~A exists in the %POS% Folder >> Logs.txt
    ) else (
        echo %%~A does not exists in the %POS% Folder 
		echo %date:~-10%%time:~0,8%:%%~A does not exists in the %POS% Folder >> Logs.txt
    )
)
REM End Check POST Folder

REM Start Check PRE Folder
for %%A in ("%DualServer%" "%Proxy%" "%SHA2%") Do (
	timeout /t 1 >nul
    if exist "%Drive%\%PRE%\%%~A" (
        echo %%~A exists in the %PRE% Folder
		echo %date:~-10%%time:~0,8%:%%~A exists in the %PRE% Folder >> Logs.txt
    ) else (
        echo %%~A does not exists in the %PRE% Folder 
		echo %date:~-10%%time:~0,8%:%%~A does not exists in the %PRE% Folder >> Logs.txt
    )
)
REM End Check PRE Folder

REM Start ERRORMAPDRIVE
:ERRORMAPDRIVE
echo Error mapping drive on %1
echo %date:~-10% %time:~0,8%:Error mapping drive on %1! Possible firewall issue. Check station status in RSS and deploy firewall fix. >> Error.txt
REM End ERRORMAPDRIVE

Re: LABEL Being Processed without GOTO or CALL

Posted: 22 Jun 2018 18:24
by Squashman
Batch files execute all lines, top to bottom unless you use code to tell it not to execute anymore. So either use a goto :eof or exit to stop the batch file.

Re: LABEL Being Processed without GOTO or CALL

Posted: 22 Jun 2018 19:35
by dbenham
Actually you probably want EXIT /B (terminate the batch file without killing the command process) instead of EXIT (kills the entire command process and closes the console window).

EXIT /B is functionally identical to GOTO :EOF

Re: LABEL Being Processed without GOTO or CALL

Posted: 22 Jun 2018 21:34
by aecnrn
dbenham wrote:
22 Jun 2018 19:35
Actually you probably want EXIT /B (terminate the batch file without killing the command process) instead of EXIT (kills the entire command process and closes the console window).

EXIT /B is functionally identical to GOTO :EOF
Won't that kill the loop though? Say if EXIT /B is specified at the end of the line, the batch will not process the next IP in the text file, right?

Re: LABEL Being Processed without GOTO or CALL

Posted: 22 Jun 2018 22:55
by Squashman
You need to put an EXIT /B or GOTO :EOF before the label :ERRORMAPDRIVE.

Re: LABEL Being Processed without GOTO or CALL

Posted: 22 Jun 2018 23:09
by aecnrn
Squashman wrote:
22 Jun 2018 22:55
You need to put an EXIT /B or GOTO :EOF before the label :ERRORMAPDRIVE.
That works perfectly. Thank you Squashman and Dbenham!

Re: LABEL Being Processed without GOTO or CALL

Posted: 06 Sep 2020 15:32
by CJM
A helpful practice I now use: adding an obvious visual barrier between sections that aren't intended to fall through. Example:

Code: Select all

@ECHO Off & SetLocal EnableDelayedExpansion
:Main
ECHO	We're going to call Sub1 now...
CALL:Sub1
ECHO	End :Sub1 [%=ExitCode%:%ErrorLevel%]
ECHO	We're going to call Sub2 now...
CALL:Sub2
ECHO	End :Sub2 [%=ExitCode%:%ErrorLevel%]
EXIT /b
________

:Sub1	Handle xxxx stuff
@ECHO	%0 %* [%=ExitCode%:%ErrorLevel%]
REM do stuff here
GOTO:EoF
________

:Sub2	Do something else
@ECHO	%0 %* [%=ExitCode%:%ErrorLevel%]
REM do other stuff here
IF ERRORLEVEL 1 EXIT /b %ErrorLevel%
________

:Error	Change screen to RED as a visual indicator
Color 47
:Exit	with any final/clean-up statements
@ECHO	%0 %* [%=ExitCode%:%ErrorLevel%]
:EoF	in case Command Extensions are Disabled, allows GOTO:EoF to function as originally intended
I use: ________, which is 7 or 8 (to help align with tab stops) underscores ("_") which I find to be the most visible, normally appearing as an unbroken line in most editors. For me, it's the right balance of aiding visibility without appreciably increasing the size/weight of the file. Plus, it makes the following section's :Label a bit more prominent.

Notes:
  • It clearly, visibly defines modular code sections, helping me to scroll through faster and helping others to initially gauge a script's structure.
  • I do not REM the separator lines because they're not supposed to be executed anyway, therefore...
  • ...As a debugging aide, if you start seeing '________' command errors, it means you've forgotten a GOTO/EXIT somewhere, as I have intentionally included a failing in :Sub2 if ERRORLEVEL is 0.

Re: LABEL Being Processed without GOTO or CALL

Posted: 07 Sep 2020 07:17
by miskox
@CJM: good idea. Thanks!

Saso

Re: LABEL Being Processed without GOTO or CALL

Posted: 07 Sep 2020 10:37
by dbenham
There is a problem with this code snippet:
CJM wrote:

Code: Select all

IF ERRORLEVEL 1 EXIT /b %ErrorLevel%
________
That will generate a visible error if ERRORLEVEL is <= 0.

Better to use ======================= as that character parses as white space, so no error. The equal sign is easier to type as well.

Alternatively prefix your divider with :: so that it is an un-callable label and also doesn't generate an error. Then you can use any character you want for your divider, including underscore.

Code: Select all

if ERRORLEVEL 2 EXIT /B %ErrorLevel%
======================

:: OR

if ERRORLEVEL 1 EXIT /B %ErrorLevel%
::____________________

Dave Benham

Re: LABEL Being Processed without GOTO or CALL

Posted: 07 Sep 2020 12:17
by aGerman
dbenham wrote:
07 Sep 2020 10:37
The equal sign is easier to type as well.
Highly dependent on the keyboard layout. It's [Shift]+[0] on my QWERTZ keyboard :lol:
But I also prefer characters that don't generate errors. Usually I just write a line of colons. I've also seen that people indent the code of subruotines. With keeping the labels unindented you'll get a nice visual separation where you'll easily find the labels. All in all a matter of taste though :wink:

Steffen

Re: LABEL Being Processed without GOTO or CALL

Posted: 08 Sep 2020 22:45
by CJM
dbenham wrote:
07 Sep 2020 10:37
There is a problem with this code snippet:
CJM wrote:

Code: Select all

IF ERRORLEVEL 1 EXIT /b %ErrorLevel%
________
That will generate a visible error if ERRORLEVEL is <= 0.

Better to use ======================= as that character parses as white space, so no error. The equal sign is easier to type as well.

Alternatively prefix your divider with :: so that it is an un-callable label and also doesn't generate an error. Then you can use any character you want for your divider, including underscore.
Yeah, I slipped that flaw in there. In fact, I had a feeling that dbenham would find it. :D

As I mentioned, having that failing code snippet was intentional, to demonstrate that a non-comment divider produces helpful errors, actually serving as a debugging aide: If you start receiving command errors on the section separator, then (as OP reported) you've got a problem in your code falling through where it should not be (since, as the coder, you put the separators there to help you visualize the impenetrable section barriers in the first place).
aGerman wrote:
07 Sep 2020 12:17
But I also prefer characters that don't generate errors. ...
So, yes my choice of separators for this purpose:
  • should NOT be re-written as comments, and to aide debugging is intended to cause errors if inadvertently executed
  • was chosen to maximize the appearance of an impenetrable barrier, synonymous with lines that should not be crossed
Making them comments would defeat one of their functions: raising errors to point-out coding/structure flaws.

I do agree that visual grouping elsewhere in lines that may be intended for execution should be in the form of benign comments, but not for the purpose I'm suggesting: as a helpful visual/debugging aid for dividing lines that should not be crossed.

Chris

Re: LABEL Being Processed without GOTO or CALL

Posted: 09 Sep 2020 04:09
by dbenham
Good idea. I would never use it, but I see how it can be helpful to some.

Re: LABEL Being Processed without GOTO or CALL

Posted: 12 Oct 2020 21:33
by T3RRY
CJM wrote:
08 Sep 2020 22:45

So, yes my choice of separators for this purpose:
  • should NOT be re-written as comments, and to aide debugging is intended to cause errors if inadvertently executed
  • was chosen to maximize the appearance of an impenetrable barrier, synonymous with lines that should not be crossed
Making them comments would defeat one of their functions: raising errors to point-out coding/structure flaws.

I do agree that visual grouping elsewhere in lines that may be intended for execution should be in the form of benign comments, but not for the purpose I'm suggesting: as a helpful visual/debugging aid for dividing lines that should not be crossed.

Chris
actually, there is a comment syntax that supports the error flagging goal here.

Code: Select all

%=:                                                                                           Section.labelname =% || Exit /B 1
if fallthrough occurs, expansion of the undefined variable will attemp to execute a file with the name Section.labelname, which will fail except in the event you actually have a file named such, and output:

Code: Select all

'Section.labelname' is not recognized as an internal or external command,
operable program or batch file.
alternately, you could define a simple macro to catch fall through if you want to stick with a distinct line divider

Code: Select all

Set "__________________________________________________________________________________________=Echo/@ & Exit /B 1"
%__________________________________________________________________________________________:@=LabelName%
or you could just throw some LF's in the substring modification to provide clearer output at the console

Code: Select all

@Echo off
(Set lf=^


%= DNR =%)
Setlocal Enabledelayedexpansion

%=:"______________________________________!LF!Section.labelname!LF!________________________________________"=% || Exit /B 1
output:

Code: Select all

'"______________________________________
Section.labelname
________________________________________"' is not recognized as an internal or external command,
operable program or batch file.

Re: LABEL Being Processed without GOTO or CALL

Posted: 14 Oct 2020 14:21
by CJM
T3RRY wrote:
12 Oct 2020 21:33
CJM wrote:
08 Sep 2020 22:45

So, yes my choice of separators for this purpose:
  • should NOT be re-written as comments, and to aide debugging is intended to cause errors if inadvertently executed
  • was chosen to maximize the appearance of an impenetrable barrier, synonymous with lines that should not be crossed
Making them comments would defeat one of their functions: raising errors to point-out coding/structure flaws.

I do agree that visual grouping elsewhere in lines that may be intended for execution should be in the form of benign comments, but not for the purpose I'm suggesting: as a helpful visual/debugging aid for dividing lines that should not be crossed.

Chris
actually, there is a comment syntax that supports the error flagging goal here.

Code: Select all

%=:                                                                                           Section.labelname =% || Exit /B 1
if fallthrough occurs, expansion of the undefined variable will attemp to execute a file with the name Section.labelname, which will fail except in the event you actually have a file named such, and output:

Code: Select all

'Section.labelname' is not recognized as an internal or external command,
operable program or batch file.
alternately, you could define a simple macro to catch fall through if you want to stick with a distinct line divider

Code: Select all

Set "__________________________________________________________________________________________=Echo/@ & Exit /B 1"
%__________________________________________________________________________________________:@=LabelName%
Although I'm intrigued by BOTH the "expansion of the undefined variable" and macro methods, the undefined variable in this case merely substitutes one error for another.

I'm more interested in the macro method since it offers more function.

So much so, I've actually MADE it my ACTUAL section exit routine, which:
  • Replaces BOTH the GOTO/EXIT and my "_______" visual module separator lines, effectively a 2-in-1
  • Instead of erroring on an unintentional fall-through, actually prevents it by exiting the section as originally (visually) intended!
  • Displays current exit codes
  • Let's me sub the @ character for additional statements, where helpful
  • Accepts an optional ErrorLevel to be set upon exiting the section
  • Still provides the visual (impenetrable) section barrier/guide (with minimal bulk) as I originally intended

Code: Select all

SetLocal&Set "_______=@Call Echo/Exit: %%0 [RC=%%=ExitCode%% EL=%%ERRORLEVEL%%]&Exit /B"

Call:Start This Now
GOTO:Exit
%_______%

:Start %1=What %2=When
@ECHO=Begin: %0 %*
@ECHO=Starting: %1
@ECHO=When: %2
%_______% 2

:Exit
@ECHO=Beg: %0 %*
%_______:@=@echo Real EoF&%
Thank you, T3RRY!