Get return code from command within FOR loop.
Posted: 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: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]: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.batand the command line results: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: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:
An excerpt from Help for FOR: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.
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!
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>
SetReturn.bat
Code: Select all
@Exit /B %~1 9339
Code: Select all
L:\Programs>Call SetReturn 0&echo.returned !errorlevel!
returned 0
L:\Programs>Call SetReturn 1&echo.returned !errorlevel!
returned 1
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
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.
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.