returning var back to calling batch file

谁都会走 提交于 2019-12-13 18:06:30

问题


i start a batch file to process some code, at a time it calls another batchfile and should get returned a variable, but the methods explained in man pages about local/endlocal seem not to work here, what am i doin wrong please?

first batch file:

@ECHO OFF
setlocal
call secondbatchfile.bat xyz
echo. [%val1%]

second batch file:

@if (@a==@b) @end /*                        <== btw what does this code do ???
@echo off
setlocal enabledelayedexpansion
set "URL=%~1"
set bla bla ...
do bla bla ...

for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (

rem trim whitespace from beginning and end of line
for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"

rem test that trimmed line matches "variable=number"
echo !line! | findstr /i "^to[a-z]*=[0-9]*" >NUL && (

rem test was successful.  Scrape number.
for /f "tokens=2 delims==" %%x in ("%%I") do set "val1=%%x"

echo !val1!                            <== this works
ENDLOCAL & SET top=%val1%              <== this not

)
)

this results in:

c:\test>firstbatchfile.bat
123456789                                   <== this works
 []                                         <== this not

i tried different syntax of return var like !val1! or %%val1 - none worked. what am i missing?

UPDATE: regarding to other example here on site i tried:

call seconbatchfile.bat xyz ret1
echo. [%2%] [%ret1%]

and in secon file changed:

rem ENDLOCAL & SET %2=!val1!

does not work either?

SOLUTION:

second batch file can be origin script from rojo reading out the whole website, i did leave the trim and match syntax lines to only return relevant matches:

for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (

rem trim whitespace from beginning and end of line
for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"

rem test that trimmed line matches "variable=number"
echo !line! | findstr /i "^[a-z]*=[0-9]*" >NUL && (

echo(%%I

)
)

and the first batch file calling it will do the search for two needed parameters like this:

@ECHO OFF
setlocal
for /f "delims=" %%I in ('secondbatchfile.bat "http://xyz"') do (

echo %%I | findstr /i "top" >NUL && (

for /f "tokens=2 delims==" %%x in ("%%I") do (
set "updir=%%x"
)
)
echo %%I | findstr /i "low" >NUL && (

for /f "tokens=2 delims==" %%x in ("%%I") do (
set "lowdir=%%x"
)
)
)

echo.[%updir%]
echo.[%lowdir%]

many thanks to rojo for fantastic code


回答1:


The easiest solution is to have your second batch file echo its result, and capture it using a for loop in the first batch file. Cancelling your setlocal to pass an environment variable back to the calling script is a messy affair.

first.bat:

@echo off
setlocal

for %%x in (
    "http://10.0.0.1/foo/vars.txt"
    "http://10.0.0.1/bar/vars.txt"
    "http://10.0.0.1/baz/vars.txt"
    "http://10.0.0.1/qux/vars.txt"
    "http://10.0.0.1/corge/vars.txt"
) do (
    for /f "delims=" %%I in ('fetchvalue.bat "%%~x"') do (
        set "val1=%%I"
    )
    echo.[%val1%]
)

fetchvalue.bat:

@if (@a==@b) @end /*

:: fetchvalue.bat <url>
:: output the "value" part of variable=value from a text file served by http

@echo off
setlocal
if "%~1"=="" goto usage
echo "%~1" | findstr /i "https*://" >NUL || goto usage

set "URL=%~1"

for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (

    rem trim whitespace from beginning and end of line
    for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"

    rem test that trimmed line matches "variable=number"
    echo !line! | findstr /i "^to[a-z]*=[0-9]*" >NUL && (

        rem test was successful.  Scrape number.
        for /f "tokens=2 delims==" %%x in ("%%I") do echo(%%x
    )
)

goto :EOF

:usage
echo Usage: %~nx0 URL
echo     for example: %~nx0 http://www.google.com/
echo;
echo The URL must be fully qualified, including the http:// or https://
goto :EOF

JScript */
var x=new ActiveXObject("Microsoft.XMLHTTP");
x.open("GET",WSH.Arguments(0),true);
x.setRequestHeader('User-Agent','XMLHTTP/1.0');
x.send('');
while (x.readyState!=4) {WSH.Sleep(50)};
WSH.Echo(x.responseText);

Here's an example first.bat that will sort the fetched values, set low to the lowest value, and set high to the highest.

@echo off
setlocal enabledelayedexpansion

for %%x in (
    "http://10.0.0.1/foo/vars.txt"
    "http://10.0.0.1/bar/vars.txt"
    "http://10.0.0.1/baz/vars.txt"
    "http://10.0.0.1/qux/vars.txt"
    "http://10.0.0.1/corge/vars.txt"
) do (
    set low=
    for /f "delims=" %%I in ('fetchvalue.bat "%%~x" ^| sort') do (
        if not defined low set "low=%%I"
        set "high=%%I"
    )
    echo low: !low!
    echo high: !high!
)



回答2:


Your inner batch file is ending by setting an environment variable named top: set top=%val1%. You'll need to change that to set val1=%val1%.

...
echo !val1!
ENDLOCAL & SET val1=%val1%


来源:https://stackoverflow.com/questions/15560198/returning-var-back-to-calling-batch-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!