【问题标题】:returning var back to calling batch file将 var 返回到调用批处理文件
【发布时间】:2013-03-11 17:03:38
【问题描述】:

我启动一个批处理文件来处理一些代码,一次它调用另一个批处理文件并且应该返回一个变量,但是手册页中解释的关于 local/endlocal 的方法似乎在这里不起作用,请问我做错了什么?

第一个批处理文件:

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

第二个批处理文件:

@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

)
)

这会导致:

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

我尝试了不同的 return var 语法,例如 !val1!%%val1 - 没有任何效果。我错过了什么?

更新: regarding to other example here on site我试过了:

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

并在第二个文件更改:

rem ENDLOCAL & SET %2=!val1!

也不行?

解决方案:

第二个批处理文件可以是来自 rojo 读取整个网站的原始脚本,我确实保留了修剪和匹配语法行以仅返回相关匹配:

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

)
)

调用它的第一个批处理文件将搜索两个所需的参数,如下所示:

@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%]

非常感谢 rojo 的精彩代码

【问题讨论】:

  • 为什么不在内部批处理中设置环境变量?像这样set RETURNVALUE=your_value
  • @if 行完全没有任何作用,因为字符串 (@a 永远不会等于字符串 @b)。前导 @ 抑制该 ONE 语句的 echo-statement-to-console。它可能可以被安全地删除,除非正在使用一些非常晦涩的方法,就像其他一些 [batch?] 程序试图在 .bat 源中找到该字符串。
  • 但它是在内部批次中设置的,不是吗?在倒数第三行do set val1=%%x - 如果我取出 endlocal 代码段在调用批处理时结果为空?
  • Peter 是对的,第一行什么都不做 - 在批处理中但是:FOR 命令将同一个文件 (jscript "%~f0") 作为 Java 脚本调用。 Java 将 /* 解释为注释的开头(如 REM)。脚本中的其他地方应该有一个 */ 来指示“EndComment” - 就在 java 代码开始之前。因此,您可以使用与 Batch 和 Java 脚本相同的文件

标签: variables batch-file return env


【解决方案1】:

最简单的解决方案是让您的第二个批处理文件回显其结果,并在第一个批处理文件中使用for 循环捕获它。取消您的 setlocal 以将环境变量传递回调用脚本是一件麻烦事。

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);

这是一个示例 first.bat,它将对获取的值进行排序,将low 设置为最低值,并将high 设置为最高值。

@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!
)

【讨论】:

  • 哇,所以在顶部的示例中,我需要使用 %%I 来捕获解析的回显结果?我需要模块化,因为第一个文件对大约 15 个设备进行了循环,并对所有设备进行了不同的操作。对于其中一项操作,我需要您出色的 http 脚本的结果。至少我需要能够在第一个脚本中将它作为函数调用,而我认为如果不重载它会更容易阅读。作为函数调用在你眼中会是更好的方式吗?
  • @peet - 啊,好的。我拿出了组合的例子。我还更新了示例first.bat 来说明如何使用for 循环来提供另一个for 循环及其URL。
  • 我是否正确地知道我需要一个调用另一个批处理文件以使用返回的 var 的函数?我尝试了适用于舒尔的代码,因为我只需要两个可找到的 10 个变量,我正在考虑将其加倍,一个用于每个搜索(需要)值的顶部和底部。除了 for 循环之外,是否还有其他易于使用的简单函数 - 或者我可能必须扩展以返回并设置两个所需的值?无论如何,非常感谢或您的投入和努力。
  • @peet - 对不起,伙计,但我不确定你在问什么。您是否在询问是否需要使用外部批处理脚本来获取所需的值?不,这不是必需的。对于你剩下的问题,我想我需要有人帮我把two vars of findable 10 ones i was thinkin about to double it 翻译成英文。 :>
  • 对不起,我的意思是我确实需要一个像 for (call fetch.bat) 这样的函数来捕获 fetch.bat 的返回而不结束 setlocal 这将允许值保持持久性直到其他脚本运行并可能意外使用它.第二部分我的意思是,fetch.bat(你的 http 脚本)将解析大约 10 个参数,其中我只需要 2 个。为了简单起见,我正在考虑将你的 http 脚本在两个 bat 中加倍(每个一个var) 这对我来说可能更容易,而不是在一次 fetch.bat 运行中找到两个参数并返回 2 个需要的(找到的 10 个)值。
【解决方案2】:

您的内部批处理文件以设置名为top 的环境变量结束:set top=%val1%。您需要将其更改为 set val1=%val1%

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

【讨论】:

  • 你不需要改成ENDLOCAL &amp; SET val1=!val1!吗?
猜你喜欢
  • 2011-10-07
  • 2013-07-19
  • 2013-09-21
  • 2012-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-16
相关资源
最近更新 更多