![无法在批处理循环中获得正确的行为](https://linux22.com/image/1369261/%E6%97%A0%E6%B3%95%E5%9C%A8%E6%89%B9%E5%A4%84%E7%90%86%E5%BE%AA%E7%8E%AF%E4%B8%AD%E8%8E%B7%E5%BE%97%E6%AD%A3%E7%A1%AE%E7%9A%84%E8%A1%8C%E4%B8%BA.png)
我在批处理文件中使用以下循环单独调用文件中的“函数”,首先显示文本,最后检查和显示错误级别。
调用循环函数使用 2 个变量。
- 要调用的子函数名称
- 为方便用户,文本将在屏幕上回显
这些呼叫线路如下所示
call :loop BackupDatabase "Taking database backup"
call :loop StopBGService "Stopping the background service"
这是循环函数本身
:loop
:retry
echo %~2
call :%~1
IF %ERRORLEVEL% NEQ 0 (
SET ERRORLEV=%ERRORLEVEL%
ECHO Executing %~2 failed
ECHO Error Level: %ERRORLEV%
ECHO.
set /p ans=Do you want to retry %~2 [y/n]^>
if "%ans%"== "y" goto :retry
if "%ans%"== "Y" goto :retry
)
GOTO :EOF
下面你会发现每个循环调用的函数
:BackupDatabase
Perform database backup commands
GOTO :EOF
:StopBGService
Perform stop background service commands
GOTO :EOF
我遇到的问题是,当“循环”出错时,脚本应该询问是否需要重试,第一次发生这种情况时,如果您输入“n”,它仍然会重试?我反复阅读了循环脚本,但不知道为什么会这样。如果有人能解决这个问题,那将是一个很大的帮助,或者如果有人能指出一种更好的方法来实现我想要实现的目标。
答案1
问题在于 Windows 命令提示符/命令行解释器 (CLI),即 CMD.EXE,有一个错误(好吧,我相信微软认为这是一个功能),当它读取一个块结构IF … ( … )
或一个FOR
循环时,它会解释所有变量%variable_name%
立即地,在执行循环之前。在您的示例中,ans
当您进入块时 if 为 null IF %ERRORLEVEL% NEQ 0 ( … )
,那么%ans%
该块内的所有出现的 都将求值为 null,即使您在块内进行更改也是如此。如果您保持开启(或在 之前将其重新开启),ans
则可以看到这一点。ECHO
IF %ERRORLEVEL% NEQ 0
解决方法是告诉 CMD 在执行引用变量的语句时允许变量在正确的时间扩展。您可以通过添加
setlocal enabledelayedexpansion
在批处理文件开头附近的某个地方,将用户对话框代码更改为如下形式
set /p ans=Do you want to retry %~2 [y/n]^>
if "!ans!" == "y" goto :retry
if "!ans!" == "Y" goto :retry
使用表格激活延迟扩展。请参阅和了解更多信息。!variable_name!
SET /?
SETLOCAL /?