【问题标题】:Calling an internal "function" in CMD script not updating the variable在 CMD 脚本中调用内部“函数”而不更新变量
【发布时间】:2012-01-23 22:36:35
【问题描述】:

在我前几天拼凑在一起的这个 NT cmd shell\“批处理文件”中,我正在使用call 命令到run sections of the script like functions——就像我之前在其他脚本中做过很多次一样。但是其中之一是行为很奇怪,我无法弄清楚可能出了什么问题......

问题在于,第一次调用该函数时,它会正确返回错误代码并设置(全局)变量%RESULT%,但以后每次再次调用它时都无法使用新的错误代码更新变量。

这是相关代码的精简版本:

:FACL
REM run fileacl.exe with given OPTIONS (%1)
REM uses global variables %TARGET% and %LOGPATH%, sets global %RESULT%
setlocal
set _OPTIONS_=%*
fileacl.exe "%TARGET%" %_OPTIONS_% /SILENT >%LOGPATH%\temp.out 2>%LOGPATH%\temp.err
set _RESULT_=%ERRORLEVEL%
if defined DEBUG echo INSIDE FUNCTION: _RESULT_ = %_RESULT_%
endlocal & set RESULT=%_RESULT_% & goto :EOF

函数的调用方式如下:

call :FACL /LINE
if defined DEBUG echo AFTER TEST #1: RESULT = %RESULT%
...
call :FACL /INHERIT /REPLACE /FORCE
if defined DEBUG echo AFTER FIX #2: RESULT = %RESULT%

你看到那些if defined DEBUG... 行了吗?他们向我展示了在函数内部,后续调用成功,因此打印出预期的 %_RESULT_% 为 0,但全局 %RESULT% 保持不变。这是一些示例输出:

TEST #1:
INSIDE FUNCTION: _RESULT_ = 107  <-- that's what I expect for the first call
AFTER TEST #1: RESULT = 107      <-- the variable was properly set after the first call

FIX #2:
INSIDE FUNCTION: _RESULT_ = 0    <-- command succeeded :)
AFTER FIX #2: RESULT = 107       <-- variable didn't change :(

RETEST:
INSIDE FUNCTION: _RESULT_ = 0    <-- succeeded again
AFTER RETEST: RESULT = 107       <-- still didn't change

您可能会问:您还尝试过什么?好的:

  1. 删除了setlocal\endlocal 技巧,只使用了全局%RESULT% 变量
  2. 在每次调用函数之前明确未定义 %RESULT%%_RESULT_%(例如 set RESULT=

...所有结果都相同。我这里有什么遗漏吗?

【问题讨论】:

  • 我使用this script 重现了与您的情况相似的情况,结果与您的结果不同,即每次都不同,就像我预期的那样。顺便说一句,您是否意识到您在endlocal 行上的%_RESULT_% 之后存储了一个额外的空间?我不确定这是否与您当前的问题有关,只是让您知道。
  • 注意额外的空间!我通过使用SET /A RESULT=... 解决了这个问题,以确保存储的值是一个数字。

标签: function batch-file cmd


【解决方案1】:

不能确定,因为我们看不到上下文中的实际代码。但是,如果 FIX 2 CALL 和 ECHO 位于带括号的块内 - 可能作为 IF 语句或 FOR 循环的一部分,则您所描述的行为是可以预期的。

如果是这种情况,那么您需要在括号内使用延迟扩展,因为整个块在执行之前被解析并且 %RESULT% 在解析时被扩展。

使用SET EnableDelayedExpansion 启用延迟扩展,使用!RESULT! 代替%RESULT% 在执行时而不是在解析时获取RESULT 的值。

【讨论】:

  • dbenham,你完全正确:随后的“函数”调用都在一个带括号的 IF 块中!我经常使用延迟扩展,但没想到在这里应用。
猜你喜欢
  • 2021-03-16
  • 2022-11-21
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多