批处理-无法从函数中的变量中返回正确的值

时间:2019-09-08 14:05:06

标签: batch-file variables windows-7

我已经阅读了很多有关使用变量从批处理函数返回值的示例和问题,但是我不能强迫Windows 7 x64 cmd.exe为我执行此操作。 ;-)

我已经尝试了很多代码示例,但是没有任何工作像我预期的那样。我编写了一个简短的批处理程序以查找如何执行此操作,但是它也没有按我预期的那样工作。我找不到我在做什么错。

@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

我希望set %1=!a!将设置:TestFunc返回的唯一变量。但是结果是:

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

最让我惊讶的是,%~1主体中有两个变量:TestFunc-一个是在本地设置的,另一个是传递给函数的,也可能是由函数返回的,但在函数主体内部未更改。

修改

最后,感谢@Stephan,我的工作正常了:

@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

和结果:

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

有两个技巧:

  1. 将第一个变量名称(x)放入另一个变量(y)值,并以两个变量名称作为参数调用该函数
  2. @Stephan的技巧是在EndLocal子句(EndLocal & set "%~1=%a%")之后设置返回的变量值。

1 个答案:

答案 0 :(得分:3)

set %~1=!a!设置一个以%~1的值命名的变量(在您的示例中为10)。因此命令被解析为:set 10=111

(您不应使用以数字开头的变量名)

我想你要做的是:

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

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

我离开echo on来看看解析器如何“翻译”您的代码。

主要技巧是使变量在endlocal中生存。这是通过用行endlocal & set "%~1=%tmpvar%欺骗解析器来实现的; %tmpvar%实际上是在 endlocal生效之前进行评估的。