Get return code from command within FOR loop.

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Get return code from command within FOR loop.

#1 Post by thefeduke » 28 Jan 2016 20:40

This query came about from a combination of several topics that exposed me to a few environment boundaries.
I am having trouble processing commands based on return codes [Edited - passed from commands within the IN(...) clause of the FOR command.
[Edited - a partial solution has been posted http://dostips.com/forum/viewtopic.php?p=45091#p45091 later in this topic.
Here is what I selected as a workable solution. The command of interest is FINDREPL which searches for a string within the batch script itself, returning the number of lines found. FindRC.bat:

Code: Select all

@Echo Off
    Echo(
    SetLOCAL EnableDelayedExpansion

    If Exist "FindRC.txt" Echo.>"FindRC.txt"
    Set "1st="
    For /F "tokens=*" %%A In (
         'Call findrepl /I /N "Error" ^<"FindRC.bat" ^
          ^&call echo %%^^errorlevel%%^>"FindRC.txt"'
    ) DO (
        If ".!1st!" NEQ ".1" (
            Echo(
            Echo(%%A
        )
        Set "1st=1"
    )

    set "SavedRC="
    <"FindRC.txt" Set /P SavedRC=
    Echo.ERRORlevel setting found as %SavedRC% exiting IN clause.
    Echo(
    Exit /B !ErrorLevel!
This code was introduced later in this topic at http://www.dostips.com/forum/viewtopic.php?p=45167#p45167 as well as a larger and more descriptive version that shows the workings.
The rest of the original first post follows.


Here are two examples from the command line. [I am looking to retrieve their return codes if they are run as commands within FOR]:

Code: Select all

L:\Programs>Echo.ABC|Call FindStr /I "abc"&echo.returned !errorlevel!
ABC
returned 0

L:\Programs>Echo.ABC|Call FindStr "abc"&echo.returned !errorlevel!
returned 1

L:\Programs>
I cannot seem to get away from depending upon using console output to do conditional processing. This seems too restrictive when a command shows good return code discipline. Here is a routine that, for demonstration purposes, does very little, much like true.bat and false.bat in DOSTips functions.
SetReturn.bat

Code: Select all

    @Exit /B %~1 9339
and the command line results:

Code: Select all

L:\Programs>Call SetReturn 0&echo.returned !errorlevel!
returned 0

L:\Programs>Call SetReturn 1&echo.returned !errorlevel!
returned 1
Here is some code that uses the above to demonstrate my limitation with a workaround, so that I can talk to what I was trying to do:

Code: Select all

@Echo Off 
SetLOCAL EnableDelayedExpansion
    Set "Ref=0"
    If .%~1 NEQ . Set "Ref=%~1" 
::
Rem.DOS Testing Environment '0' easy to find temporary folder
    Set "tmpd=%TEMP%\'0'"
    If Not Exist "%tmpd%" MkDir "%tmpd%"
:: temporary script used for command within FOR construct
(
    echo(@Echo Off
    echo(Echo Setting %%~1 by %%~nx0
    echo(Exit /B %~1% 9339
)>%tmpd%\%~n0_temp.bat

:: Demonstrate target result outside the FOR
    Call "%tmpd%\%~n0_temp.bat" %Ref%
    Echo.errorlevel now %errorlevel%
:: Set to error condition
    Call :SetReturn 1
    Echo.errorlevel now %errorlevel%
       
    For /F "tokens=1-4*" %%A In (
    '"%tmpd%\%~n0_temp.bat" %Ref%'
    ) DO (
        Echo.Variables '%%A %%B %%C' mean that '%%D' ran somewhere.
        Echo.ERRORlevel setting remains at !errorlevel!
        Echo.Can be set sometimes by interpreting meaningful output.
        Call :SetReturn %%B directly from the command output.
        Echo.!errorlevel!
        Exit /B !ErrorLevel! 9339
    )
    Echo.In case the For did not exit
    Exit /B %ErrorLevel% 9339

:SetReturn
    Echo.Setting %~1 by :SetReturn
    Exit /B %~1% 9339

I have tried to manipulate the content of the IN('...') clause to get something useful with &,&& and || both within the '...' and multiple ones, with and without escaping. Some were syntactically acceptable but never acted on the second phrase. Was I trying something impossible? As can be seen from the following output, I was able to achieve conditional processing, but was completely dependent on deciphering the console output of the ECHO that I added to the bare function to retrieve the return code of 7 set within the FOR:

Code: Select all

L:\Programs>findretc 7 &Echo.&Echo finally returned !ErrorLevel!
Setting 7 by FindRetC_temp.bat
errorlevel now 7
Setting 1 by :SetReturn
errorlevel now 1
Variables 'Setting 7 by' mean that 'FindRetC_temp.bat' ran somewhere.
ERRORlevel setting remains at 1
Can be set sometimes by interpreting meaningful output.
Setting 7 by :SetReturn
7

finally returned 7

An excerpt from Help for FOR:

Code: Select all

Finally, you can use the FOR /F command to parse the output of a
command.  You do this by making the file-set between the
parenthesis a back quoted string.  It will be treated as a command
line, which is passed to a child CMD.EXE and the output is captured
into memory and parsed as if it was a file.
Maybe this processing takes place on an island, the passage for which I cannot pay the ferry-man.
Any ideas on a different(better) approach, given that this describes my objective well enough? I have observed nested FOR loops and commands that set the return code to the number of changes made that, in combinations, could benefit.
Thanks for considering,
John A.
Last edited by thefeduke on 03 Feb 2016 23:39, edited 2 times in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Get results - DO commands within FOR loop.

#2 Post by foxidrive » 28 Jan 2016 23:30

I began to read your question and couldn't immediately see what your aim is.

There's too much extra detail for me to wade through to try and see why - can you explain simply what you need to do with the errorlevel?

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get results - DO commands within FOR loop.

#3 Post by thefeduke » 28 Jan 2016 23:50

foxidrive wrote:There's too much extra detail for me to wade through to try and see why - can you explain simply what you need to do with the errorlevel?
Sure. Ideally I want to retrieve the return code of the DOS command executed within single quotes in the FOR /F construct. [Edit: correction]
John A.
Last edited by thefeduke on 29 Jan 2016 00:06, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Get results - DO commands within FOR loop.

#4 Post by foxidrive » 28 Jan 2016 23:53

Can you give an example of a command you want to get the errorlevel from?
Do you need text from the command or just the errorlevel?

I presume you mean for /F

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get results - DO commands within FOR loop.

#5 Post by thefeduke » 29 Jan 2016 00:20

The first example of my first post is an example of the behavior of FINDSTR return codes showing the presence or absence of matching data from which a decision can be made for further action.
John A.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get results - DO commands within FOR loop.

#6 Post by thefeduke » 29 Jan 2016 02:17

I am interested in the behavior of a command that issues a return code within a 'FOR /F' command. This is a theoretical question to gain understanding. There was an interesting thread on determining the ECHO state in batch without using a temporary file. Why bother, if you can type 'ECHO', or just use that temporary file?

FINDSTR is an example of a command for which the return code is useful. Another example for study is the simplistic command that I coded to do nothing but return a value. It does no more than is necessary to demonstrate behavior (1) in the command line. (2) in a batch script, (3) as a called label routine, (4) as a called external command and (5) within the FOR command. FINDREPL is interesting in that: The total number of matchings/replacements is returned in ERRORLEVEL.

Not worrying about difficult, I do not have a specific task to solve and so cannot fail. The contents of 'command' in IN('command') appear to be more restrictive than what can be done in a command prompt, but I have exhausted my limitations before defining those of the system.

The batch scripters seldom have accepted the MS limitations of 'working as designed' and I hope might shed some light on whether catching that resulting code is possible.

John A.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get results - DO commands within FOR loop.

#7 Post by thefeduke » 29 Jan 2016 16:04

I have discovered the largest part of the answer to my own question. The forum participation has worked to stimulate the thought process. I am still hoping for some feedback about manipulating the actual command string in the IN('command') clause of FOR to allow multiple commands and the && and || conditional operators.

I have created a "wrapper" temporary script file to put around the actual command of interest. This wrapper is executed by FOR and saves the return code to another temporary file for later retrieval.

Code: Select all

@Echo Off
SetLOCAL EnableDelayedExpansion

    If .%~1 NEQ . Set "FindstrOption=%~1"
::
Rem.DOS Testing Environment '0' easy to find temporary folder
    Set "tmpd=%TEMP%\'0'"
    If Not Exist "%tmpd%" MkDir "%tmpd%"
:: temporary script used as an wrapper for the command within FOR construct
(
    Echo(@Echo Off
Rem.Insert below: escaped command to be run
    Echo(Echo.ABC^|Call FindStr %FindstrOption% abc"
Rem.Insert above: escaped command to be run
    Echo(Echo.%%errorlevel%% return code stored by %%~nx0 ^>"%%tmpd%%\%%~n0_Return.txt"
    Echo(Exit /B %%ErrorLevel%% 9339
)>%tmpd%\%~n0_temp.bat

    Echo(
    Call :SetReturn 211
    Echo.errorlevel verified as %errorlevel% for baseline ERROR condition
   
    If Exist "%tmpd%\%~n0_Temp_Return.txt" Erase "%tmpd%\%~n0_Temp_Return.txt"
    For /F "tokens=1-4*" %%A In (
    '"%tmpd%\%~n0_temp.bat"'
    ) DO (
        If ".!1st!" NEQ ".1" (
            Echo(
            Echo.Variable '%%A' indicates that the wrapper ran somewhere.
            Echo.ERRORlevel setting remains at !errorlevel!
        )
        Set "1st=1"
    )

    Echo(
    Echo.Retrieve ERRORLEVEL from the wrapper saved return code file.
    set "SavedRC="
    <"%tmpd%\%~n0_Temp_Return.txt" Set /P SavedRC=
    Echo.%SavedRC%
    Call :SetReturn %SavedRC% from the saved return code file.
    Echo.Conditional processing can now initiate or run after '%~nx0'
    Echo.errorlevel verified as %errorlevel% to be returned by '%~nx0'
    Echo(
    Exit /B !ErrorLevel! 9339

:SetReturn
    Echo.ERRORLEVEL Set to %~1 by :SetReturn
    Exit /B %~1% 9339
This script will cause FINDSTR to fail unless the argument '/I' is passed to make FINDSTR case insensitive giving these results:

Code: Select all

G:\Programs>findretc /I& Echo ERRORLEVEL !errorlevel! resulted from FindRetC.b

ERRORLEVEL Set to 211 by :SetReturn
errorlevel verified as 211 for baseline ERROR condition

Variable 'ABC' indicates that the wrapper ran somewhere.
ERRORlevel setting remains at 211

Retrieve ERRORLEVEL from the wrapper saved return code file.
0 return code stored by FindRetC_temp.bat
ERRORLEVEL Set to 0 by :SetReturn
Conditional processing can now initiate or run after 'FindRetC.bat'
errorlevel verified as 0 to be returned by 'FindRetC.bat'

ERRORLEVEL 0 resulted from FindRetC.bat

G:\Programs>findretc & Echo ERRORLEVEL !errorlevel! resulted from FindRetC.bat

ERRORLEVEL Set to 211 by :SetReturn
errorlevel verified as 211 for baseline ERROR condition

Retrieve ERRORLEVEL from the wrapper saved return code file.
1 return code stored by FindRetC_temp.bat
ERRORLEVEL Set to 1 by :SetReturn
Conditional processing can now initiate or run after 'FindRetC.bat'
errorlevel verified as 1 to be returned by 'FindRetC.bat'

ERRORLEVEL 1 resulted from FindRetC.bat
This approach does not rely on the content of the output data.

John A.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: Get return code from command within FOR loop.

#8 Post by dbenham » 29 Jan 2016 20:27

thefeduke wrote:Maybe this processing takes place on an island, the passage for which I cannot pay the ferry-man.

Yep - the commands within the IN() clause are executed in a brand new cmd.exe process. Also, FOR /F buffers the result, and the commands execute to completion before iterations commence. So all variables and ERRORLEVEL that are set by the commands disappear by the time the FOR /F loop begins to iterate.

thefeduke wrote:I have created a "wrapper" temporary script file to put around the actual command of interest. This wrapper is executed by FOR and saves the return code to another temporary file for later retrieval.

Booyah :!: You've arrived upon a solution :D
But as you suspected, you don't need a wrapper script - You can accomplish the same thing directly within the IN() clause using &. One issue is the delayed expansion state within the IN() clause is disabled by default, regardless of the delayed expansion state within the parent script. Your two choices are to use CALL to delay the expansion of %ERRORLEVEL%, or to execute your commands with an explicit CMD /V:ON so you can use delayed expansion. When just dealing with ERRORLEVEL, I like to use the CALL method.

The CALL statement within the IN() clause will be parsed a total of 3 times.

The IN() clause is executed using a command line context, not a batch file. So you need CALL ECHO %^ERRORLEVEL%. The caret causes the variable to not be recognized on the 1st command line pass, but then the caret disappears. So on the 2nd command line pass (after CALL), the %ERRORLEVEL% is expanded properly with the true dynamic value.

But the IN() clause must also be parsed by the batch script, meaning the percents must be escaped as %%, and the caret must be either quoted or escaped as ^^.

If your command does not require any quotes, then you can simply enclose the entire IN() clause in double quotes, which are within the single quotes. This works because the IN() clause is executed via CMD /C, which will strip the enclosing double quotes before executing the commands.

Code: Select all

for /f .... in('"someCommand&call echo %%^errorlevel%%>returnCode.txt"') do ...

But if your command requires its own double quotes around the command and/or any arguments, then adding an additional set can mess up the quoting. In this case you want to escape all the poison characters:

Code: Select all

for /f ... in('someCommand "arg1 value" "arg2&value"^&call echo %%^^errorlevel%%^>returnCode.txt') do ...


So here I'll setup a full working example. Suppose the command you want to run is test.bat that randomly prints between 1 and 5 lines, and returns a random errorlevel between 0 and 2.

test.bat

Code: Select all

@echo off
setlocal
set /a cnt=%random% %% 5, rtn=%random% %% 3
for /l %%N in (0 1 %cnt% ) do echo Line %%N
exit /b %rtn%


Now in this first example, suppose you simply want your FOR /F loop to print out each line of output, and then afterwards, print out the resultant errorlevel

test1.bat

Code: Select all

@echo off
setlocal
for /f "delims=" %%A in (
  '"test.bat&call echo %%^errorlevel%%>return.txt"'
) do (
  echo %%A
)
set /p "rtn=" <return.txt
echo ERRORLEVEL=%rtn%

--SAMPLE OUTPUT (4 runs)--

Code: Select all

C:\test>test1
Line 0
ERRORLEVEL=2

C:\test>test1
Line 0
Line 1
Line 2
Line 3
ERRORLEVEL=2

C:\test>test1
Line 0
Line 1
Line 2
Line 3
Line 4
ERRORLEVEL=1

C:\test>test1
Line 0
Line 1
ERRORLEVEL=0


But suppose you only want to process the lines if the returned ERRORLEVEL is 0. Remember that the IN() clause is executed to completion before any iterations, so the solution is actually quite simple :)
test2.bat

Code: Select all

@echo off
setlocal
for /f "delims=" %%A in (
  '"test.bat&call echo %%^errorlevel%%>return.txt"'
) do findstr /x 0 return.txt >nul && (
  echo %%A
)
set /p "rtn=" <return.txt
echo ERRORLEVEL=%rtn%

--SAMPLE OUTPUT (4 runs)--

Code: Select all

C:\test>test2
ERRORLEVEL=1

C:\test>test2
Line 0
Line 1
ERRORLEVEL=0

C:\test>test2
ERRORLEVEL=1

C:\test>test2
Line 0
Line 1
Line 2
Line 3
Line 4
ERRORLEVEL=0

C:\test>test2
ERRORLEVEL=2


One potential problem with the above is the return code is checked each iteration - not very efficient. But we are already using a temp file, so why not write the output of test.bat to a temp file, and then conditionally process the output with FOR /F only if the ERRORLEVEL is 0. One can argue that you should always process via a temp file if the output is long because FOR /F can become very slow if it has to buffer a large output - it doesn't know how big a buffer is needed until the command finishes, so there can be many reallocations, causing performance to be non-linear. Using a temp file results in linear performance.

test3.bat

Code: Select all

@echo off
setlocal
call test.bat >output.txt
:: Save the ERRORLEVEL, just in case the FOR loop corrupts the value
set "rtn=%errorlevel%"
if %rtn% equ 0 for /f "delims=" %%A in (output.txt) do (
  echo Line %%A
)
echo ERRORLEVEL=%rtn%

Output is formatted identically as test2.bat


Dave Benham

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Get return code from command within FOR loop.

#9 Post by Aacini » 29 Jan 2016 21:57

@thefeduke: Excuse me, I apologize in advance for this reply.

Although your description is extensive, you don't go to the point of the topic. You should know that in this types of problems you must be as concise and clear as possible; any detail not related to the problem just distract our attention. Also, if you include some code you must previously explain what is the purpose of such example. I hate topics that don't explain what the problem is, but that include extensive code (that certainly I not review).

Your first example is this:

Code: Select all

Echo.ABC|Call FindStr /I "abc"&echo.returned !errorlevel!

If you want that this code show the returned errorlevel in the screen when it is executed in a FOR /F command, use this:

Code: Select all

for /F "delims=" %%a in ('cmd /V:ON /C Echo.ABC^^^|Call FindStr /I "abc"^^^&echo.returned !errorlevel!') do echo %%a

However, in this case the "returned !errorlevel!" text is mixed up with the output of FindStr. If you want to set the errorlevel to the value returned by FindStr after FOR command ends, you may use this:

Code: Select all

for /F "delims=" %%a in ('cmd /V:ON /C Echo.ABC^^^|Call FindStr /I "abc"^^^&echo exit /B !errorlevel!^^^> setForErrorlevel.bat') do echo %%a

call setForErrorlevel
echo returned %errorlevel%

Finally, if you want to set the errorlevel to 1 if the FOR command did not processed any data, that in this case is an equivalent result of FindStr errorlevel, you may use this:

Code: Select all

rem Reset errorlevel to 0
ver > NUL

(for /F "delims=" %%a in ('Echo.ABC^|Call FindStr /I "abc"') do echo %%a) || rem

echo returned %errorlevel%

For a further explanation of this last example, see the description of "Exit Code management" at this SO answer.

Antonio

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get return code from command within FOR loop.

#10 Post by thefeduke » 29 Jan 2016 22:42

dbenham wrote:But as you suspected, you don't need a wrapper script - You can accomplish the same thing directly within the IN() clause using &.
This time the blind squirrel found the nut in the wrapper. Thank you, Dave, for affirming that it is possible and even showing the direct method.
dbenham wrote:The CALL statement within the IN() clause will be parsed a total of 3 times.
Ahhh, I am so glad to have sparked a passion to get this insightful look into the nuts and bolts.
dbenham wrote:But suppose you only want to process the lines if the returned ERRORLEVEL is 0. Remember that the IN() clause is executed to completion before any iterations, so the solution is actually quite simple
We certainly need a 'tongue-in-cheek' emoticon for that statement!
I really appreciate that you took the time and trouble to go into such detail in your solution and explanation. This is real brain food.
John A.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get return code from command within FOR loop.

#11 Post by thefeduke » 29 Jan 2016 23:21

Aacini wrote:@thefeduke: Excuse me, I apologize in advance for this reply.
It's not yours to apologize for my overly convoluted thinking. I get lost in my own detail. You cut to the chase perfectly. I was so overwhelmed with all of the escaping required to do anything that I gave up without even knowing if it could be done. I can certainly work with your examples and appreciate the information link.
I am so glad to have attracted your attention. You and Dave have given me plenty this evening to let me experiment for quite a while.
Thank you,
John A.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get return code from command within FOR loop.

#12 Post by thefeduke » 03 Feb 2016 17:00

Aacini wrote:For a further explanation of this last example, see the description of "Exit Code management"
I used your very valuable table and ran case after case of your two suggestions, trying to explain to myself the results until the output stopped confusing me. They produce the expected output only under specific conditions. The first suggestion is substantially the same as the second shown here:
Aacini wrote:However, in this case the "returned !errorlevel!" text is mixed up with the output of FindStr. If you want to set the errorlevel to the value returned by FindStr after FOR command ends, you may use this:

Code: Select all

for /F "delims=" %%a in ('cmd /V:ON /C Echo.ABC^^^|Call FindStr /I "abc"^^^&echo exit /B !errorlevel!^^^> setForErrorlevel.bat') do echo %%a

call setForErrorlevel
echo returned %errorlevel%
This code, when I ran it, substituted an empty string for !errorlevel!, Echod 'EXIT /B ' to the console and created an empty file for "setForErrorlevel.bat" from the redirection. One doesn't notice the empty file being run because there are no errors and the echo'd 'returned 0' is as expected, but only by the two deceptive coincidences: that the prevailing ERRORLEVEL began as zero and that the code used the /I flag that produces matches which make one expect zero from FINDSTR.
I inserted one space between !errorlevel! and '^^^>' and the redirection worked properly, matching the results of your first suggestion about just displaying the ERRORLEVEL. I ran test cases influencing the active ERRORLEVEL prior to the FOR command and concluded, using "Table 4 - Special cases" that the return code sent to "setForErrorlevel.bat" was not that of FINDSTR but that of the CALL command which succeeded in all cases and did not reset the ERRORLEVEL.
Edited: What seemed to clear yesterday does now not seem as plausible. After more experimentation, I am not satisfied. I have experimented with CMD outside of FOR using multiple commands. CMD seems to affect the return code by just running. CMD itself is not on the reference table, so I am guessing that an 'EXIT /B 0' is implied if no code changing commands were run. Is it possible that CMD.exe terminates when it encounters the first '&' or "|" character and that the "prior ERRORLEVEL" is influenced by the time that checking is being done? So much happens under the covers, perhaps, such as brackets being implied? That kind of thing confuses my anticipated order of precedence. So I am still tweaking "(", ")" and "&" combinations. Regarding the tables, does the process of transferring control by executing a command directly imply that a CALL has occurred?
Thank you, again, for a most illuminating exercise, but this approach does not seen to apply. I certainly learned a lot. I have selected and shall post my best selection tonight.
John A.
Last edited by thefeduke on 04 Feb 2016 18:44, edited 1 time in total.

thefeduke
Posts: 211
Joined: 05 Apr 2015 13:06
Location: MA South Shore, USA

Re: Get return code from command within FOR loop.

#13 Post by thefeduke » 03 Feb 2016 17:44

Having adapted Dave's suggestion to my routine, here is a minimal example of return code retrieval from the IN() clause of the FOR command. I have changed the program sample from FINDSTR to FINDREPL (courtesy of Antonio) because of more demonstrable results.
All parameters are hardcoded for brevity in FindRC.bat:

Code: Select all

@Echo Off
    Echo(
    SetLOCAL EnableDelayedExpansion

    If Exist "FindRC.txt" Echo.>"FindRC.txt"
    Set "1st="
    For /F "tokens=*" %%A In (
         'Call findrepl /I /N "Error" ^<"FindRC.bat" ^
          ^&call echo %%^^errorlevel%%^>"FindRC.txt"'
    ) DO (
        If ".!1st!" NEQ ".1" (
            Echo(
            Echo(%%A
        )
        Set "1st=1"
    )

    set "SavedRC="
    <"FindRC.txt" Set /P SavedRC=
    Echo.ERRORlevel setting found as %SavedRC% exiting IN clause.
    Echo(
    Exit /B !ErrorLevel!

That being my solution, the following is added as an example that accepts parameters and displays more of what is happening and where. The verbose example is FindRetCode.bat:

Code: Select all

@Echo Off
    SetLOCAL EnableDelayedExpansion
    Echo(
    Echo.Command '%~n0' /I - for case insensitive
    Echo.Command '%~n0' "" "rSearch" - for different search string
    Echo(
    Echo.errorlevel found to be %errorlevel% on entry to '%~nx0'

    Set "StringOption="
    If .%~1 NEQ . Set "StringOption=%~1"
    Set "String=error"
    If .%~2 NEQ . Set "String=%~2"
    call :SetReturn 9009
    Echo.errorlevel was reset to %errorlevel% before FOR command

    If Exist "FindRC.txt" Echo.>"FindRC.txt"
    Set "1st="
    For /F "tokens=*" %%A In (
        'call echo.ERRORlevel setting found as %%errorlevel%% entering IN clause.^
         ^&Call findrepl %StringOption% "%String%" ^<"FindRetCode.bat" ^
         ^&call echo %%^^errorlevel%%^>"FindRC.txt"'
    ) DO (
        If ".!1st!" NEQ ".1" (
            Echo(
            Echo(%%A
            Echo.ERRORlevel setting remains at !errorlevel! during DO clause.
        )
        Set "1st=1"
    )

    set "SavedRC="
    <"FindRC.txt" Set /P SavedRC=
    Echo.ERRORlevel setting found as %SavedRC% exiting IN clause.
    Echo(
    Call :SetReturn %SavedRC% from the saved return code file.
    Echo.==^> Conditional processing can now be initiated using ERRORLEVEL %ErrorLevel%
    Echo.==^> as retrieved from the saved return code file
    Echo.==^> or be run afterward based on that same return code from '%~nx0'
    Exit /B !ErrorLevel!

:SetReturn
Rem.Echo.ERRORLEVEL Set to %~1 by :SetReturn
    Exit /B %~1% 9339


Antonio: if you see this, the immediately preceding post addressed to you may have hidden behind my back-to-back updates.
[Edited - I have copied the short version to the first post.
Thank you both and moderator, again.
John A.

Post Reply