返回值使用 SETLOCAL 设置调用函数的批处理文件

返回值使用 SETLOCAL 设置调用函数的批处理文件

SETLOCAL...ENDLOCAL彻底地注入局部变量,以至于尝试计算值并返回值的函数会失败。
通常,这些函数使用for-解析文件和字符串do,并依赖于SETLOCAL enabledelayedexpansion计算值。

多年来,我通过将值传递给临时文件并恢复它来解决了这个问题,如下例所示。

然而……这是 非常 速度很慢,尤其是涉及递归时,因为需要不断进行读/写/创建循环。

甚至由创建的系统范围变量也会SETX失败,因为SETLOCAL会创建并发布本地版本。它是万无一失的~或者看起来是。

多年来,我一直在研究这个问题,这个问题让我一直很头疼。也许有人已经解决了它?以下是示例代码:

示例代码

@echo off
set _str=
call :RandomFunction %*
:: back from the function
echo:
echo: now try to recover the variables
set _ & echo: _ReturnStr not there
echo:
echo: so collect it from the temp file
for /f "delims=" %%V in ('more^<_passvalue.txt') do set _str=%%V

echo: [%_str%] is returned
echo: *sigh* there must be a better way!
exit /b

该函数名为:

:RandomFunction
@echo off
set _anotherstr=asdfg

setlocal & rem most times enabledelayedexpansion

set _localReturnValue=
echo: this function is invoked and [%*] set of parameters comes in 
:: and stuff happens
:: at the end of it all a value is ready to be returned!

set "_localReturnValue=ImBreakingOut" & rem this is it
:: at the same time send it to a file
echo:%_localReturnValue%>_passValue.txt
endlocal

SET "_ReturnStr=%_localReturnValue%" & rem trying to recover it to be returned
echo: trying to echo the _ReturnStr= [%_ReturnStr%] after ENDLOCAL
echo: Post ENDLOCAL it was released
echo: but _anotherstr= [%_anotherstr%] does persist
exit /b
:: /RandomFunction

控制台的输出是

>f 123 abc
 this function is invoked and [123 abc] set of parameters comes in
 trying to echo the _ReturnStr= [] after ENDLOCAL
 Post ENDLOCAL it was released
 but _anotherstr= [asdfg] does persist

 now try to recover the variables
_anotherstr=asdfg
 _ReturnStr not there

 so collect it from the temp file
 [ImBreakingOut] is returned
 *sigh* there must be a better way!
>

答案1

答案是隧道

哦天哪。我是个白痴。
弗兰克·西纳特拉有答案。乔治·克鲁尼也有。
这叫做“隧道”啊啊啊。
天啊,我们怎么这么容易忘记。

西蒙·谢泼德在他的 SS64 网站上很好地阐述了这一点如何创建和使用批处理文件函数页:

解决这个问题的方法是利用 CMD shell 逐行评估变量的事实 - 因此将 ENDLOCAL在同一条线上因为 SET 语句给出了我们想要的结果。这种技术称为“隧道”,适用于函数和整个批处理脚本

重写代码

@echo off
call :RandomFunction %*
:: back from the function
echo:
echo: now recover the variable created in the function
echo: the value of variable _ReturnStr = [%_ReturnStr%]
echo:
echo: so no need to collect from a temp file
echo: *sigh* there has always beeen a better way!
exit /b

:RandomFunction
@echo off
setlocal & rem most times enabledelayedexpansion

set _localReturnValue=
echo: this function is invoked and [%*] set of parameters comes in 
:: and stuff happens
:: at the end of it all a value is ready to be returned!

set "_localReturnValue=ImBreakingOut" & rem this is it
:: concurrently execute the variable assignment wit the ENDLOCAL command
endlocal & SET "_ReturnStr=%_localReturnValue%"

exit /b
:: /RandomFunction

现在给出了正确答案

>_temp abc 123
 this function is invoked and [abc 123] set of parameters comes in

 now recover the variable created in the function
 the value of variable _ReturnStr = [ImBreakingOut]

 so no need to collect from a temp file
 *sigh* there has always beeen a better way!

>

相关内容