BATCH - can't return proper value in a variable from a function

一曲冷凌霜 提交于 2019-12-13 00:56:30

问题


I have read a lot of examples and questions about returning values from batch functions using variables but I can't force Windows 7 x64 cmd.exe to do it for me. ;-)

I have already tried a lot of code examples but nothing has worked as I expected. I have written a short batch program to find out how to do it, but it also hasn't worked as I expected. I can't find what I'm doing wrong.

@echo off
SetLocal EnableDelayedExpansion
set x=10
echo x(1) = !x!
call :TestFunc !x!
echo x(2) = !x!
EndLocal
exit /b

:TestFunc
SetLocal EnableDelayedExpansion
set a=%~1
echo a(1) = !a!
set /a a=a+101
echo a(2) = !a!
set %~1=!a!
echo   %%~1 = %~1
echo ^^!%%~1^^! = !%~1!
EndLocal
exit /b

I expected that set %1=!a! will set the only variable being returned by the :TestFunc. But the result is:

>test_variables.bat
x(1) = 10
a(1) = 10
a(2) = 111
  %~1 = 10
!%~1! = 111
x(2) = 10

The most surprising for me was that there are two variables %~1 inside the body of the :TestFunc - one is set locally and the other one, passed to the function and maybe also returned by the function, but not changed inside the function's body.

Edit

And finally, thanks to @Stephan, my exaple that is working:

@echo off
rem echo on
SetLocal EnableDelayedExpansion
set "x=10"
set "y=x"
echo x(1) = !x!
echo y(1) = !y!
call :TestFunc !y! !x!
echo ---------------------------------
echo x(2) = !x!
echo y(2) = !y!
EndLocal
exit /b

:TestFunc
SetLocal EnableDelayedExpansion
set a=%~2
echo a(1) = !a!
set /a a=!a!+101
echo a(2) = !a!
EndLocal & set "%~1=%a%"
exit /b

and the result:

>test_variables.bat
x(1) = 10
y(1) = x
a(1) = 10
a(2) = 111
---------------------------------
x(2) = 111
y(2) = x

There were two tricks to do:

  1. Put the first variable name (x) into the other variable (y) value and call the function with both variable names as parameters
  2. @Stephan's trick with setting returned variable value after the EndLocal clause (EndLocal & set "%~1=%a%").

回答1:


set %~1=!a! sets a variable named by the value of %~1 (which is 10 in your example). so the command is parsed as: set 10=111

(you shouldn't use variablenames starting with a digit)

What I think you want to do is:

echo on
set "var=xxx"
call :sub var 10
echo %var%
goto :eof

:sub
setlocal
set /a tmpvar=%~2+55
endlocal & set "%~1=%tmpvar%"

I left echo on to see exactly, how the parser "translates" your code.

The main trick is for the variable to survive an endlocal. This is achieved by tricking the parser with the line endlocal & set "%~1=%tmpvar%; %tmpvar% is actually evaluated before endlocal takes effect.



来源:https://stackoverflow.com/questions/57842646/batch-cant-return-proper-value-in-a-variable-from-a-function

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