Top-Themen

Aktuelle Themen (A bis Z)

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Batch - for-Schleife vorzeitig beenden

Frage Entwicklung Batch & Shell

Mitglied: NeonZero

NeonZero (Level 1) - Jetzt verbinden

29.08.2008, aktualisiert 18.10.2012, 23110 Aufrufe, 11 Kommentare

Hallo.

Ich möchte eine for-Schleife vorzeitig beenden und suche nach Ideen dafür. Hier der Code, der verdeutlichen soll, was ich meine:
01.
for %%a in (a b c d e) do (  
02.
  echo %%a 
03.
  if "%%a" == "c" break_loop 
04.
05.
------------------------------------------- 
06.
gewünschte Ausgabe:	 
07.
08.
09.
c
Lösung 1: Eine mögliche Lösung wäre der folgende Code:
01.
::Der folgende Code wurde nach einem Hinweis von bastla (siehe seinen Beitrag weiter unten) 
02.
::derart angepasst, dass hier auf setlocal EnableDelayedExpansion verzichtet werden kann. Thx 
03.
 
04.
for %%a in (a b c d e) do if not defined _break ( 
05.
  echo %%a 
06.
  if "%%a" == "c" set _break=now 
07.
)
Dieser Ansatz hat den Nachteil, dass d und e weiterhin durchlaufen werden, auch wenn der Block dabei nicht abgearbeitet wird. Will man mithilfe einer solchen for-Schleife z.B. eine bestimmte Information aus einer großen Datei holen, so werden – nachdem man die Information gefunden hat – auch die darauf folgenden Zeilen eingelesen. Und für jede Zeile wird die if-Abfrage abgearbeitet, was je nach Größe der Datei unnötig viel Zeit in Anspruch nimmt.

Lösung 2: Das zuvor beschriebene Problem lässt sich mit dem folgenden Code umgehen:
01.
call :FncMyForLoop 
02.
goto :EOF 
03.
 
04.
:FncMyForLoop 
05.
  for %%a in (a b c d e) do ( 
06.
    echo %%a 
07.
    if "%%a" == "c" exit /b 0 
08.
09.
 exit /b 1
Der Code hat gleichzeitig den Vorteil, dass man anhand des Errorlevels erkennen kann, ob „c“ gefunden wurde, oder nicht (nach dem call-Aufruf: if %errorlevel% == 1 echo c wurde nicht gefunden! ).

Diese Lösung ist allerdings sehr umständlich, da man für jede for-Schleife eine eigene Funktion schreiben müsste. Viel besser wäre es, wenn man die for-Schleife direkt zu einem Abbruch zwingen kann. Um genau solche Lösungsansätze geht es in diesem Thread.

Bye, nz
Lösung 3: Benutzer ahe hat weiter unten den folgenden Ansatz eingebracht.
01.
for %%a in (a b c d e) do (  
02.
  echo %%a 
03.
  if "%%a" == "c" goto :Weiter 
04.
05.
:Weiter 
06.
echo Hier geht es weiter ...
Eine noch idealere Lösung wäre es, wenn man die for-Schleife einfach beenden könnte, ohne den Umweg über die Sprungmarke zu gehen. Andernfalls müsste man für jede dieser for-Schleifen eine eigene Sprungmarke setzen (was zugegebenermaßen ein eher kleines Übel wäre). Hat jemand dafür eine Idee? –- NeonZero 29.08.2008 18:19
Mitglied: ahe
29.08.2008 um 17:36 Uhr
Hallo,

reicht dir das vielleicht schon:

01.
@echo off 
02.
for %%a in (a b c d e) do (   
03.
	echo %%a  
04.
	if "%%a" == "c" exit /b  
05.
) 
Die Ausgabe am Prompt sieht dann so aus:
a
b
c

mfg
Axel
Bitte warten ..
Mitglied: NeonZero
29.08.2008 um 17:46 Uhr
Hallo Axel und danke für Deine Antwort.

Die Idee ist nicht schlecht, hat nur leider den Nachteil, dass dadurch umgehend die Batch beendet wird. Ziel ist es nicht, die obige Ausgabe zu erhalten, sondern eine allgemein verwendbare Möglichkeit zu finden, die for-Schleife (und nicht die Batch) vorzeitig zu beenden. Die Zielstellung habe ich offensichtlich nicht eindeutig formuliert. Mein Fehler. Sorry.

Bye, nz
Bitte warten ..
Mitglied: ahe
29.08.2008 um 17:59 Uhr
Ach so... mmh, das gehe doch zu einer Sprungmarke... danach kannst Du auch noch andere Dinge ausführen...

01.
@echo off 
02.
for %%a in (a b c d e diedeldum gnuffz c c d d) do (   
03.
	echo %%a  
04.
	if "%%a" == "c" goto WEITER  
05.
)  
06.
 
07.
:WEITER 
08.
echo es geht weiter 
09.
goto DA 
10.
 
11.
:DA 
12.
echo Jetzt bin ich da 
13.
 
14.
:END 
15.
echo Laeuft bis zum Ende 
16.
echo. 
17.
echo und tschuess...
mfg
Axel
Bitte warten ..
Mitglied: NeonZero
29.08.2008 um 18:22 Uhr
Ein schöner Ansatz. Danke. Ich habe ihn oben als Nachtrag aufgelistet.

Bye, nz
Bitte warten ..
Mitglied: bastla
29.08.2008, aktualisiert 18.10.2012
Hallo NeonZero!

Eine etwas abgewandelte Version Deiner ersten Variante kommt ohne "delayedExpansion" aus:
01.
@echo off & setlocal 
02.
set done= 
03.
for %%a in (a b c d e) do if not defined done ( 
04.
  echo %%a 
05.
  if "%%a"=="c" set done=break 
06.
)
Einfach aus der Schleife herauszuspringen ist zwar auch möglich, aber von Biber nicht empfohlen ...

Grüße
bastla
Bitte warten ..
Mitglied: NeonZero
29.08.2008 um 21:12 Uhr
Hallo bastla.

Das ist ein guter Vorschlag. Ich habe den Code oben mit einem Hinweis auf Deinen Beitrag entsprechend angepaßt. Danke.

Zum verlinkten Beitrag: " Das "Verlassen" einer FOR-Anweisung ist eigentlich vom sympathischen Weltmarktführer nicht vorgesehen, geschweige denn zugesichert. " (Biber)

@Biber (falls Du mitliest): Woher stammt diese Information und mit welche Auswirkungen ist zu rechnen? Hast Du (oder sonst jemand) diesbezüglich eigene Erfahrungen gemacht?

Bye, nz
Bitte warten ..
Mitglied: bastla
29.08.2008 um 22:30 Uhr
Hallo NeonZero!

Weil Du oben zur Variante mit der "Schalter"-Variable meintest:
Dieser Ansatz hat den Nachteil, dass d und e weiterhin durchlaufen werden, auch wenn der Block dabei nicht abgearbeitet wird. Will man mithilfe einer solchen for-Schleife z.B. eine bestimmte Information aus einer großen Datei holen, so werden – nachdem man die Information gefunden hat – auch die darauf folgenden Zeilen eingelesen. Und für jede Zeile wird die if-Abfrage abgearbeitet, was je nach Größe der Datei unnötig viel Zeit in Anspruch nimmt.
Um eine bestimmte Information aus einer großen Datei zu holen, wird sich oftmals "findstr" anbieten, etwa:
01.
for /f "delims=" %%i in ('findstr /c:"bestimmte Information" "D:\Große Datei.txt"') do ...
Je nach Verwendungszweck kann es dann noch sinnvoll sein, die Zeilennummern (für einen späteren "direkten" Zugriff) mit angeben zu lassen ("/n") und durch "Hintereinanderschalten" mehrerer Suchvorgänge die Anzahl der tatsächlich per Schleife zu bearbeitenden Zeilen zu reduzieren ...

Grüße
bastla
Bitte warten ..
Mitglied: Biber
30.08.2008 um 01:50 Uhr
Moin NeonZero,

zu dem nicht empfohlenen (und nicht vorgesehenen) Verlassen einer FOR-Schleife.
M$ hat in den (relativ umfangreichen) Dokumentationen zu FOR und CALL und GOTO nie erwähnt, ob und welche der FOR-Anweisungen gefahrlos unvollendet bleiben können.
Wir reden doch hier (nur zur Erinnerung) von einem Befehlsinterpreter namens CMD.exe, der eigentlich jeden vom CMD-Prompt abgesetzten Befehl xy (oder auch einen Batch abc.bat) am Dienstag um 13h exakt so interpretieren sollte wie am Freitag um 04:23h.
Aber schon durch einen Batch-Programmabbruch (z.B. ein Syntaxfehler) in einem Batch mit einigen der "neueren" Sprachelemente wie
- Setlocal/Endlocal
- EnableExtensions/EnableDelayedExpansion bzw. der Disable-Gegenstücke...
... merkst Du sehr schnell, dass die CMD.exe sehr empfindlich auf geöffnete und nicht geschlossene Klammern (das sind diese Elemnte ja) reagiert.
Plötzlich befindest Du Dich -aus eimem Batch herausgeflogen- am CMD-Prompt und das "Echo ist OFF" - der häufigste und harmloseste Fall.
Oder aber Du bist am CMD-Prompt in einem Zustand, in dem Du lokale (setlocal) Variablen anlegen kannst - was eigentlich nur im Batch und nie am CMD-Prompt gehen sollte.

Nun sind seit W2000 noch ein paar lustige FOR-Anweisungsvarianten dazugekommen - zur "schon immer" vorhandenden For-ein-paar-Elemente-durchwackel-Anweisung sind rekursive Konstrukte (FOR /R) und vor allem FOR-Anweisungen dazugekommen, die Files/Filehandles/Verzeichnisstrukturen/Fremdfunktionen nutzen/öffnen/anfordern.
Was passiert denn mit einer für eine For/F-Anweisung zum Lesen geöffneten Datei, wenn das Lesen/die FOR-Anweisung niemals endet? Was passiert in einer rekursiv angelegten FOR/R-Anweisung, wenn Du das Wurzelelement löscht? Oder in einer FOR/D-Anweisung? Wie viele Stacks/Caches/Buffers/Pushs und Pops hat denn die CMD.exe reserviert oder allokiert und wieviele freigegeben bei einer unvollendeten Schleife?

Das mag testen wer will, aber in Batchabläufen, die im produktiven Umfeld laufen (z.B. zur Datensicherung oder Update-Gewährleistung) möchte ich NICHTS riskieren, das Seiteneffekte hervorrufen könnte. Oder eben dazu führt, dass sich ein und derselbe Batch je nachdem was vorher so gelaufen ist, am Dienstag um 13h anders verhält als Freitags morgens.
...ich verhalte mich auch montags nicht anders as mittwochs...

Grüße
Biber
Bitte warten ..
Mitglied: NeonZero
30.08.2008 um 09:27 Uhr
Hallo Biber.

Das, was Du beschrieben hast, ist ein grundsätzliches Problem. Wenn mir Konsole-Programme, die in C geschrieben wurden, während der Entwicklung abgestürzt sind, gab es ähnliche Effekte, gerade was das Environment anbelangt. Diese traten aber nie auf, wenn das Programm durch lief.

Ein für die cmd.exe unerwarteter Absturz einer Batch oder eines beliebigen Konsoleprogramms kann schlimme Auswirkungen haben. Denn die Konsole besteht danach weiter. Sie ist so rudimentär, dass sie – anders als bei einer Windows-Applikation – hierfür keine Schutzmechanismen anbietet (einmal abgesehen von konzeptionellen Ansätzen wie start, oder setlocal, die die Arbeitsweise einschränken oder nur bedingt „schützen“ können). Ein Konsoleprogramm, das danach in derselben Konsole aufgerufen wird, läuft daher in einer nahezu undefinierten Umgebung. Deshalb ist es hier umso wichtiger, Programmierfehler zu vermeiden, die einen Absturz zur Folge haben könnten. Das gilt gleichermaßen für Batches, C-Programme, oder was auch immer.

Verhindern kann man dieses Verhalten, indem man start verwendet, also jedes Konsoleprogramm in einer eigenen cmd.exe-Umgebung ausführt. Dann muss man sich aber darüber im Klaren sein, das die Konsoleprogramme so keinen Einfluss mehr auf die Umgebung des Aufrufers nehmen können (auch eine Batch ist dann nicht mehr in der Lage, eine Variable der ursprünglichen Konsole direkt zu ändern).

Wenn MS die Stack-Behandlung der cmd.exe nicht vollkommen verbockt hat, sollten auch bei Batches sämtliche Sprünge aus Schleifen / Funktionen / Blöcken, gleich welcher Art, korrekt abgearbeitet und zum Ende des Programms sauber abgeschlossen werden. Das bedeutet z.B. auch, dass die oben erfragte Datei, die in der for-Schleife geöffnet wurde, ordentlich geschlossen wird (inkl. Freigabe sämtlicher Handle, etc.), sobald die Batch ein reguläres Ende findet. Dann nämlich werden auch sämtliche for-Schleifen, aus die man herausgesprungen ist, regulär beendet (so sollte es zumindest sein).

Daher nun meine Frage, ob solche Probleme auch dann beobachtet wurden, wenn die Batch nicht an einem für die cmd.exe unerwarteten Punkt abgestürzt ist. Denn wenn man Probleme mit dem Environment hat, obgleich die Batch ohne Programmierfehler durch lief, ist das ein sicheres Zeichen dafür, dass die cmd.exe tatsächlich unsauber arbeitet und solche Sprünge nicht verkraftet.

Bye, nz
Bitte warten ..
Mitglied: tom1stein
12.01.2018, aktualisiert um 14:38 Uhr
Microsoft beschreibt nirgends, dass eine for-Schleife nicht mit einem GOTO abgebrochen werden darf. Man kann also annehmen, dass dies erlaubt ist. Tatsächlich scheint intern der Interpreter sauber aufzuräumen, jedenfalls hatte ich mit einem reinen Abbruch noch nie Probleme auch in komplexen Scripten. Und undefinierte Ängste sind eh ein Hinweis-, aber kein Ratgeber. Erlaubt ist also:

01.
for (irgendetwas) do ( 
02.
  for (irgendetwasanderes) do ( 
03.
    goto Gefunden 
04.
05.
06.
:Gefunden
Diese meine Einschätzung wird gestützt durch die Tatsache, dass Sprünge, die nicht stumpf alle Ebenen verlassen, explizit abgefangen werden. Das folgende führt noch vor der echo-bedingten Anzeige zu einem '")" kann syntaktisch an dieser Stelle nicht verarbeitet werden.':

01.
echo on 
02.
for (irgendetwas) do ( 
03.
  for (irgendetwasanderes) do ( 
04.
    goto Absturz 
05.
06.
:Absturz      << Diese Zeile darf nicht hier stehen 
07.
)
Tom
Bitte warten ..
Mitglied: ahe
15.01.2018 um 17:47 Uhr
Na ja, MS hat schon am Interpreter in den letzten Jahren deutlich gedreht, manche Einstellungen verändert, manche Parameter bei Befehlen hinzugefügt, etc., so dass manche Skripte nicht mehr so laufen, wie noch vor 10 Jahren...
(wenn ich alleine an die Datum/Uhrzeit Verarbeitung oder sprachspez. Dinge denke...)

Eigentlich wird auch immer mehr der Fokus auf die Powershell gelegt, als in den "alten" Kommandointerpreter... der wird nur noch notgedrungen, vermutlich aus Kompatibilitätsgründen, mitgezogen...


mfg
Axel


. . . da fühlt man sich doch tatsächlich wieder jünger, wenn man seine alten Beiträge nach ca. 10 Jahren mal wieder sieht...

Ist fast wie ein Schulfreund nach 20-30 Jahren zu sehen und soger wiederzuerkennen...
Bitte warten ..
Ähnliche Inhalte
Batch & Shell
Batch Schleife als FOR-SCHLEIFE
gelöst Frage von mp2711Batch & Shell2 Kommentare

Mit den FOR-Schleifen habe ich mich leider bislang zu selten auseinander gesetzt, aber da ich sonst gerade nicht weiter ...

Batch & Shell
Batch - Hilfe bei FOR-Schleife
gelöst Frage von makroll10Batch & Shell8 Kommentare

Hallo, aus einer Access-Datenbank heraus rufe ich per VBA den u.a. Batch mit den Parametern: Reports!UB_System!Pfad ("C:\Users\User\Documents\Polar\") und Reports!UB_Polar!hrmexport1 ...

Batch & Shell
Batch Variablen in for-Schleife
gelöst Frage von Dacki1107Batch & Shell2 Kommentare

Hallo Liebe Administratoren Ich kämpfe mit einem kleinen Problemchen und hoffe das Ihr mir helfen könnt. Ich versuche eine ...

Batch & Shell
Batch Problem bei einer For Schleife
gelöst Frage von Juergen42Batch & Shell2 Kommentare

Hallo Ich komme nicht dahinter ist sicher nur ein kleines Problem, aber es wird keine Ausgabe gemacht Eigentlch willich ...

Neue Wissensbeiträge
Mac OS X

MacOS wo ist die Tilde ?

Tipp von Alchimedes vor 46 MinutenMac OS X

Hallo, ich hab eine MacOS qwertz Keyboard auf US Layout umgestellt da die Sonderzeichen besser ereichbar sind. Leider fehlt ...

Datenschutz

Weitere Inforamtionen zum Sicherheitsproblem BeA

Information von Penny.Cilin vor 7 StundenDatenschutz

Im folgenden ein weiterer Bericht über die Sicherheitsprobleme von Bea. Fataler Konstruktionsfehler im besonderen elektronischen Anwaltspostfach Gruss Penny

Windows 10

Systemdienste behalten nach Win10 inplace-Upgrade nicht die ggf. modifizierte Startart bei

Tipp von DerWoWusste vor 9 StundenWindows 103 Kommentare

Stellt Euch vor, Ihr habt ein Win10 System und modifiziert dort die Startart von Systemdiensten. Zum Beispiel wollt Ihr ...

Microsoft Office

Deaktivieren von Startbildschirm und Backstage-Ansicht in Office 2016 per Batch-Datei

Anleitung von SarekHL vor 12 StundenMicrosoft Office17 Kommentare

Guten Morgen zusammen! Ich habe mir gestern (auch mit Hilfe dieses Boards) ein Script gebastelt, um in Office 2016 ...

Heiß diskutierte Inhalte
Netzwerke
NTFS-Berechtigung
Frage von Daoudi1973Netzwerke23 Kommentare

Hallo zusammen und frohes neues Jahr (Sorry, ich bin spät dran) Meine Frage: 1- Ich habe einen Ordner im ...

Batch & Shell
AD-Abfrage in Batchdatei und Ergebnis als Variable verarbeiten
gelöst Frage von Winfried-HHBatch & Shell19 Kommentare

Hallo in die Runde! Ich habe eine Ergänzungsfrage zu einem alten Thread von mir. Ausgangslage ist die Batchdatei, die ...

Microsoft Office
Deaktivieren von Startbildschirm und Backstage-Ansicht in Office 2016 per Batch-Datei
Anleitung von SarekHLMicrosoft Office17 Kommentare

Guten Morgen zusammen! Ich habe mir gestern (auch mit Hilfe dieses Boards) ein Script gebastelt, um in Office 2016 ...

Windows 10
Netbook erkennt Soundkarte nicht - keinerlei Info zum Hersteller und Modell vom Netbook und Hardware bekannt
Frage von fyrb38Windows 1017 Kommentare

Guten Tag, meine Schwester reist in einigen Wochen für ein paar Monate ins Ausland und hat sich dafür ein ...