在暂停期间中断批处理脚本执行

mel*_*okb 5 pause batch-file

我正在开发一个复杂的、长时间运行的批处理脚本,在调试时遇到了一个小问题。我有一个打开到脚本根路径的命令行窗口,因此我可以键入myscript.bat以将其关闭以进行测试。我PAUSE在语句之间使用命令来观察脚本的行为。但是,我发现在PAUSE取消执行的命令期间键入 CTRL+C 只会被解释为继续执行的键,而不是按预期中断脚本。

我知道我可以简单地终止/关闭命令窗口,但每次在新的命令窗口中导航回正确的路径有点烦人。有没有一种方法可以在批处理脚本当前处于 时轻松地正确中断它的执行PAUSE


编辑:正如@dbenham 所指出的,它PAUSE看起来在简单的脚本中工作得很好。PAUSE但是,如果迭代内嵌套有多个语句FOR,则不能在FOR迭代中间中断 - 只能在最后中断。这是演示该问题的示例脚本:

@echo off

for /l %%y in (2008, 1, 2013) do (
    echo 1
    pause
    echo 2
    pause
    echo 3
    pause
    echo 4
    pause
    echo 5
    pause
)
Run Code Online (Sandbox Code Playgroud)

如果您尝试终止前四个PAUSE语句中的任何一个,您会发现您的终止命令被忽略并且执行仍然继续。但是,一旦到达末尾,即第五个PAUSE,您就会收到终止提示(在下面的示例输出中,我在每个提示时都按 CTRL+C):

Z:\>test
1
Press any key to continue . . .
2
Press any key to continue . . .
3
Press any key to continue . . .
4
Press any key to continue . . .
5
Press any key to continue . . .
Terminate batch job (Y/N)? y
Run Code Online (Sandbox Code Playgroud)

有什么想法如何防止这种行为?

dbe*_*ham 5

它在 Win 7(32 位)上运行良好

这是一个简单的测试脚本

@echo off
echo Before
pause
echo After
Run Code Online (Sandbox Code Playgroud)

当我在不按 的情况下运行上述命令时<Ctrl-C>,我得到以下信息:

D:\test>test
Before
Press any key to continue . . .
After

D:\test>
Run Code Online (Sandbox Code Playgroud)

当我按<Ctrl-C>“按任意键”提示时,我得到:

D:\test>test
Before
Press any key to continue . . .
Terminate batch job (Y/N)? y

D:\test>
Run Code Online (Sandbox Code Playgroud)

编辑:后续问题的解决方案

它不需要处于循环中。任何带括号的代码块都存在该问题。整个块被一次性解析,然后从内存中执行。

(
  echo Before 1
  pause
  echo Before 2
  pause
  echo After
)
Run Code Online (Sandbox Code Playgroud)

我认为使用 PAUSE 命令没有修复方法。但我有一个简单的解决方案,应该可以提供您想要的调试功能。只需确保在运行脚本之前尚未定义 PAUSE 环境变量即可。

@echo off

:: ------------------------------------------------------
:: Include this block of code at the top of your script
::
setlocal
if not defined pause (
  set "pause=choice /m "........................Continue "&if errorlevel 2 exit"
  cmd /c ^""%~f0" %* ^"
  exit /b
)
:: ------------------------------------------------------


:: Now use %pause% instead of pause anywhere you want within your script
:: Press Y to continue, N to quit
:: The script will immediately terminate if you press N, even if in the
:: middle of a CALL

:: Here is a simple demonstration

call :sub1
exit /b

:sub1
call :sub2
exit /b

:sub2
for /l %%N in (1 1 3) do (
  echo ----- %%N ------
  echo Before 1
  %pause%
  echo Before 2
  %pause%
  echo After
)
exit /b
Run Code Online (Sandbox Code Playgroud)