Batch-Skript-Ausführung während der Pause unterbrechen

11385
mellamokb

Ich entwickle ein komplexes, langwieriges Batch-Skript und bin beim Debuggen auf ein kleines Problem gestoßen. Ich habe ein Befehlszeilenfenster zum Wurzelpfad des Skripts geöffnet, sodass ich myscript.bates eingeben kann, um es zum Testen auszulösen. Ich verwende PAUSEBefehle zwischen Anweisungen, um das Verhalten des Skripts zu überwachen. Ich entdeckte jedoch, dass die Eingabe von STRG + C während eines PAUSEBefehls zum Abbrechen der Ausführung einfach als Schlüssel zum Fortsetzen der Ausführung interpretiert wird, anstatt das Skript wie beabsichtigt zu brechen.

Ich weiß, dass ich das Befehlsfenster einfach töten / schließen kann, aber es ist etwas ärgerlich, wenn Sie in einem neuen Befehlsfenster immer wieder zum richtigen Pfad zurückkehren. Gibt es eine Möglichkeit, die Ausführung eines Batch-Skripts einfach zu brechen, während es sich gerade in einem befindet PAUSE?


Edit: Es sieht aus wie PAUSEin einfachen Skripten funktioniert, wie von @dbenham angezeigt. Wenn Sie jedoch mehrere PAUSEAnweisungen in einer FORIteration verschachtelt haben, können Sie nicht mitten in der FORIteration aufbrechen - nur am Ende. Hier ist ein Beispielskript, das das Problem veranschaulicht:

@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 ) 

Wenn Sie versuchen, eine der ersten vier PAUSEAnweisungen zu beenden, werden Sie feststellen, dass Ihr Beendigungsbefehl ignoriert wird und die Ausführung trotzdem fortgesetzt wird. Wenn Sie jedoch das Ende erreicht haben PAUSE, erhalten Sie die Aufforderung zum Beenden (in der Beispielausgabe unten drückte ich bei jeder Aufforderung STRG + 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 

Irgendwelche Ideen, wie man dieses Verhalten verhindern kann?

3

2 Antworten auf die Frage

3
dbenham

Es funktioniert gut für mich unter Win 7 (32 Bit)

Hier ist ein triviales Testskript

@echo off echo Before pause echo After 

Wenn ich den obigen Vorgang ohne Drücken ausführte <Ctrl-C>, erhalte ich Folgendes:

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

Wenn ich <Ctrl-C>bei der Eingabeaufforderung " Drücken Sie eine beliebige Taste" drücke, bekomme ich:

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

EDIT: Lösung für Folgefrage

Es muss nicht in einer Schleife sein. Das Problem besteht bei jedem geklammerten Codeblock. Der gesamte Block wird in einem Durchgang analysiert und dann aus dem Speicher ausgeführt.

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

Ich glaube nicht, dass es eine Lösung gibt, die den Befehl PAUSE verwendet. Aber ich habe eine einfache Lösung, die die gewünschte Debug-Funktionalität bieten sollte. Stellen Sie nur sicher, dass die PAUSE-Umgebungsvariable nicht bereits definiert ist, bevor Sie Ihr Skript ausführen.

@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 
Hmm, I do too. There must be something unique about my script. Let me see if I can make a script that reproduces the problem. mellamokb vor 11 Jahren 0
@mellamokb - Leiten Sie die Eingabe an einem beliebigen Punkt um? dbenham vor 11 Jahren 0
Nope. But I am using a lot of nested `if`/`for` clauses, something like `for /l %%y in (2012, 1, 2013) do ( ... pause ... )` mellamokb vor 11 Jahren 0
I think I figured it out. If there are multiple `pause` statements inside of a single `for` iteration, then you can't actually break the script until the end of that iteration. Weird. Try this script for example, and you can't break the first for `pause` statements: http://pastebin.com/BEtSKBer mellamokb vor 11 Jahren 0
@mellamokb - Ich habe eine Lösung angehängt, die in Codeblöcken funktionieren sollte. Es war ein interessantes Problem zu lösen. dbenham vor 11 Jahren 0
That is an awesome idea! Thanks for taking the time to look at it. This should work great. mellamokb vor 11 Jahren 0
1
stevek_mcc

Eine Möglichkeit, das Problem PAUSEin geklammerten Blöcken zu überwinden, ist das Aufrufen einer Subroutine:

@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 ) 

Dies löst das Problem zumindest in Windows 10 und ermöglicht benutzerdefinierte Meldungen für PAUSE.