从调用的批处理文件中接收变量

Posted

技术标签:

【中文标题】从调用的批处理文件中接收变量【英文标题】:Receive variable from a called batch file 【发布时间】:2021-10-21 05:56:57 【问题描述】:

我这里有两个批处理文件,test.batlen.bat

len.bat 是一个函数,它接收来自test.bat 的输入,对其进行处理,然后将结果值返回给test.bat

test.bat

@echo off
setlocal EnableDelayedExpansion
call len tesla
echo !result!
pause

len.bat

@echo off
setlocal EnableDelayedExpansion
set "string=%~1"
for /l %%a in (0,1,10000) do if "!string:~%%a,1!" == "" (
    set result=%%a
    exit /b
)

当我打开test.bat 时,我希望它会打印一个值。相反,它说 Echo 已关闭。 将变量从len.bat 传递到test.bat 似乎存在问题。

【问题讨论】:

我建议你阅读setlocal的目的。所以从len.bat中删除delayedexpansion 我假设您知道您的长度逻辑非常低效。对于初学者,批处理文件中的字符串NEVER 可以是 10,000 字节长。如果您搜索该站点,您会发现完成此任务的代码效率更高。 【参考方案1】:

setlocal 可以被认为是一个沙箱,只要沙箱存在,在该沙箱内创建的任何东西都会存在。当调用 endlocal 时,沙箱停止存在 - 无论是显式调用,还是在脚本结束时隐式调用。

len.bat 中,您使用第二个setlocal enabledelayedexpansion 命令在沙箱内添加一个沙箱,然后在该内部沙箱内创建!result!。当len.bat 结束时,!result! 被销毁,因为在调用len.bat 之前它并不存在。

我怀疑您添加了第二个setlocal enabledelayedexpansion,因为您认为需要在len.bat 内部使用延迟扩展,但实际上延迟扩展仍然启用,因为它在test.bat 中已打开。

len.battest.bat 中删除setlocal enabledelayedexpansion 将正确返回“5”。

如果您觉得需要将setlocal enabledelayedexpansion 保留在len.bat 中以将其与test.bat 分开使用,您可以显式调用endlocal 并将set 命令链接到它以欺骗解释器让变量逃离沙箱。

@echo off
setlocal EnableDelayedExpansion
set "string=%~1"
for /l %%a in (0,1,10000) do if "!string:~%%a,1!" == "" (
    endlocal & set result=%%a
    exit /b
)

【讨论】:

如果从批处理文件启动,这会很好。但是,如果我在 cmd 中运行 call len tesla,它不会打印任何内容,我在调用该函数之前尝试了 setlocal 一行,但它仍然无法正常工作。需要帮助 @Darwish - len.bat 没有 echo 命令,因此它永远不会打印任何内容。该值存储在变量%result% 中,因此脚本结束后,您可以键入echo %result% 以获取字符串长度。如果要更新脚本以显示字符串长度,只需在 endlocalexit /b 行之间添加 echo %%a 是的,在调用 len.bat 后,我​​从 cmd 回显变量。但它打印!结果!与实际值不同。我什至尝试了 echo %result% ,但它仍然不打印该值。 I can't replicate your problem. 哦,我明白了,我没有在 len.bat 中放入 endlocal【参考方案2】:

这对您有帮助吗?字符串长度返回为%ErrorLevel%:

新的len.bat

@Set "str=#%~1" & SetLocal EnableDelayedExpansion
@Set "len=0" & For /L %%G In (12,-1,0) Do @(Set /A "len |= 1 << %%G"
    For %%H In (!len!) Do @If "!str:~%%H,1!" == "" Set /A "len &= ~ 1 << %%G")
@EndLocal & Exit /B %len%

示例 test.bat

@Call "len.bat" four
@Echo %ErrorLevel% & Pause
@Call "len.bat" "nineteen inc spaces"
@Echo %ErrorLevel% & Pause

【讨论】:

@set 和 set 有什么区别 @setset@callcall@echoecho。打开命令提示符窗口,然后从那里运行test.bat,在随机删除一些@ 字符形成批处理文件后,看看它们做了什么! @ 防止命令行/块被打印到屏幕上。许多人使用echo off 行来对脚本中的所有内容执行此操作,并在其前面加上@ 前缀,以防止在运行时将echo off 打印到屏幕上。 这取决于你是否在顶部有一行@Echo Off,并删除所有其他五个@ 字符,但对我来说尤其是len.bat 不需要修改并且永远不会单独运行,因为它是一个帮助脚本,只会为脚本添加六个不必要的大小字节。 @Echo Off 加上一个回车和换行对是十一个字符/字节,而五个 @ 字符只使用五个字节!

以上是关于从调用的批处理文件中接收变量的主要内容,如果未能解决你的问题,请参考以下文章

请问在批处理文件中如何使用变量

用java怎么实现从前端接收、处理并传回视频?

powershell v2.0 从批处理 cmd 文件传递​​变量计算机名参数

如何在vbs中设置可以在调用批处理脚本中读取的环境变量

批处理脚本使 setlocal 变量被其他批处理文件访问

通过从perl脚本调用的批处理文件设置环境变量