从调用的批处理文件中接收变量
Posted
技术标签:
【中文标题】从调用的批处理文件中接收变量【英文标题】:Receive variable from a called batch file 【发布时间】:2021-10-21 05:56:57 【问题描述】:我这里有两个批处理文件,test.bat
和 len.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.bat
和test.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%
以获取字符串长度。如果要更新脚本以显示字符串长度,只需在 endlocal
和 exit /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 有什么区别@set
是 set
,@call
是 call
和 @echo
是 echo
。打开命令提示符窗口,然后从那里运行test.bat
,在随机删除一些@
字符形成批处理文件后,看看它们做了什么! @
防止命令行/块被打印到屏幕上。许多人使用echo off
行来对脚本中的所有内容执行此操作,并在其前面加上@
前缀,以防止在运行时将echo off
打印到屏幕上。
这取决于你是否在顶部有一行@Echo Off
,并删除所有其他五个@
字符,但对我来说尤其是len.bat
不需要修改并且永远不会单独运行,因为它是一个帮助脚本,只会为脚本添加六个不必要的大小字节。 @Echo Off
加上一个回车和换行对是十一个字符/字节,而五个 @
字符只使用五个字节!以上是关于从调用的批处理文件中接收变量的主要内容,如果未能解决你的问题,请参考以下文章