Прервать выполнение пакетного скрипта во время паузы

11163
mellamokb

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

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

3

2 ответа на вопрос

3
dbenham

У меня на 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 
Хм, я тоже. В моем сценарии должно быть что-то уникальное. Позвольте мне посмотреть, смогу ли я сделать сценарий, который воспроизводит проблему. mellamokb 10 лет назад 0
@mellamokb - Вы перенаправляете ввод в любой момент? dbenham 10 лет назад 0
Нету. Но я использую множество вложенных выражений `if` /` for`, что-то вроде `for / l %% y в (2012, 1, 2013) do (... pause ...)` mellamokb 10 лет назад 0
Я думаю, что я понял это. Если внутри одной итерации `for` несколько операторов` pause`, вы не сможете на самом деле сломать скрипт до конца этой итерации. Weird. Попробуйте этот сценарий, например, и вы не можете разбить первый для операторов `pause`: http://pastebin.com/BEtSKBer mellamokb 10 лет назад 0
@mellamokb - я добавил решение, которое должно работать внутри блоков кода. Это была интересная проблема, чтобы решить. dbenham 10 лет назад 0
Это отличная идея! Спасибо, что нашли время посмотреть на это. Это должно работать отлично. mellamokb 10 лет назад 0
1
stevek_mcc

Один из способов решить проблему, заключенную 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.

Похожие вопросы