3

Я разрабатываю сложный, длительный пакетный скрипт и столкнулся с небольшой проблемой при отладке. У меня есть окно командной строки, открытое для корневого пути скрипта, поэтому я могу напечатать myscript.bat чтобы запустить его для тестирования. Я использую команды PAUSE между операторами для наблюдения за поведением скрипта. Однако я обнаружил, что ввод CTRL+C во время команды PAUSE для отмены выполнения просто интерпретируется как ключ для продолжения выполнения, а не как нарушение сценария, как предполагалось.

Я знаю, что могу просто убить / закрыть командное окно, но немного раздражает каждый раз возвращаться к правильному пути в новом командном окне. Есть ли способ правильно прервать выполнение пакетного скрипта, пока он находится в состоянии PAUSE?


Изменить: похоже, что PAUSE отлично работает в простых сценариях, как указано @dbenham. Однако, если у вас есть несколько операторов 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
)

Если вы попытаетесь завершить какое-либо из первых четырех утверждений PAUSE , вы обнаружите, что ваша команда terminate игнорируется и выполнение все равно продолжается. Но как только вы достигнете конца, к пятой 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

Есть идеи, как предотвратить такое поведение?

2 ответа2

3

У меня на Win 7 работает нормально (32 бита)

Вот тривиальный тестовый скрипт

@echo off
echo Before
pause
echo After

Когда я запускаю вышеупомянутое без нажатия <Ctrl-C> , я получаю следующее:

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

D:\test>

Когда я нажимаю <Ctrl-C> в ответ на запрос "Нажать любую клавишу", я получаю:

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

D:\test>

РЕДАКТИРОВАТЬ: Решение последующего вопроса

Это не должно быть в цикле. Проблема существует с любым заключенным в скобки блоком кода. Весь блок анализируется за один проход, а затем выполняется из памяти.

(
  echo Before 1
  pause
  echo Before 2
  pause
  echo After
)

Я не думаю, что есть исправление с помощью команды 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
1

Один из способов решить проблему PAUSE в круглых блоках - вызвать подпрограмму:

@echo off
goto run

:pause
echo %*
pause >nul
exit /b

:run
(
  echo Before 1
  call :pause Please consider aborting with Ctrl+C
  echo Before 2
  call :pause Really consider aborting with Ctrl+C
  echo After
)

Это решает проблему по крайней мере в Windows 10 и позволяет настраивать сообщения для PAUSE .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .