miczar
Goto Top

FOR Schleife mit LOOP und nachfolgender FOR Schleife

Hallo zusammen,

ich habe ein Problem mit einem Batchfile.

Situation:

im Netzwerk ist kein WINS mehr vorhanden und so muss ich zwangsläufig auf die gute alte LMHOSTS ausweichen.
Da die IPs aber nicht statisch sind und ich keine Lust habe alles via cmd manuell zu machen habe ich ein Batch erstellt.

Aus einer Client_list.txt sollen die darin enthaltenen Client Namen ausgelesen und als Variable gesetzt werden.

Beispielinhalt der Client_list.txt

pc1
pc2
pc3
pc4
EOL


CODE:

:getclientname
FOR /L %%H IN (client_list.txt) DO (set clientname=%%H)
IF %%H==EOL goto:end


Jetzt wo die Variable definiert ist, soll im nächsten Schritt der Ping durchgeführt, die IP ausgelesen und in nachfolgend IP und Clientname in die LMHOSTS geschrieben werden.

:getip
ping.exe -n 1 -4 %clientname% >> temp.txt
FOR /F "tokens=2 delims=" %%G IN (temp.txt) DO @echo %%G %clientname% >> lmhosts
del temp.txt
goto:getclientname


Das Problem:

als Ergebnis bekomme ich nachher die gewünschte LMHOSTS (richtige Formatierung) aber sie enthält nur einen Eintrag. Und zwar die IP und den Rechnernamen des letzten gelisteten PCs aus der Client_list.txt. Wo liegt der Fehler das die Einträge nicht zeilenweise abgearbeitet werden?

Und ich bin mir fast sicher, dass ich bei der Schleifenbildung auch irgendwo Fehler drin habe.


Vielleicht kann ja jemand helfen

Gruß
Mike

Content-Key: 308577

Url: https://administrator.de/contentid/308577

Printed on: April 16, 2024 at 04:04 o'clock

Member: narthan
Solution narthan Jun 30, 2016 at 11:29:08 (UTC)
Goto Top
Hallo Mike,

erstmal solltest du für deine 1. Schleife for /f statt /l verwenden. Soweit ich weiß benutzt man for /l nur zum erstellen von Folgen.
Dein Problem liegt aber viel eher darin, dass deine Befehle nicht in der 1. Schleife abgearbeitet werden. Deine "eigtl. übergeordnete" Schleife endet bei dir nach dieser Zeile (durch die schließende Klammer):

FOR /L %%H IN (client_list.txt) DO (set clientname=%%H)

Auch die folgende IF Bedingung wird erst nach Abschluss der Schleife betrachtet. Insofern speichert die Schleife jeden Wert der Input Datei in die Variable, aber dein Skript führt keine weiteren Befehle damit aus. Lediglich der letzte Eintrag der Txt wird somit verarbeitet. Du musst die Klammer geöffnet lassen und die weiteren Befehle in die For-Schleife integrieren. Z.B.

....
FOR /F %%h IN (client_list.txt) DO (
SET "clientname=%%h"  
IF "%%h"=="EOL" (  
GOTO :EOF
) ELSE (
ping.exe ..... :: usw. hier weitere Bearbeitung
)
)

Ich hoffe das hilft dir schon weiter. face-smile

Gruß,
narthan
Member: Biber
Solution Biber Jun 30, 2016 updated at 11:30:41 (UTC)
Goto Top
Moin miczar,

etwas verkürzt ungetestet so:
FOR /F %%i IN (client_list.txt) DO (
    IF "%%i" NEQ"EOL" (  
        FOR /F "tokens=2 delims=" %%G IN ('ping.exe -n 1 -4 %%i') DO @echo %%G %%i >> lmhosts  
         ) )

Ein Problem bei deinem Code:
Mehrfach ausgeführt nach einer FOR-Anweisung wird das, was innerhalb der Klammern nach dem "DO" steht.
Dort steht bei dir oben in der ersten FOR-Anweisung nur. set clientname=%%H.

Grüße
Biber
Member: miczar
miczar Jun 30, 2016 at 17:23:39 (UTC)
Goto Top
Hallo narthan, Hallo Biber,

Danke für eure prompte Antwort.

Wenn ich das jetzt richtig verstanden habe gehört jede Handlungsanweisung in eine eigene Klammer.
Ich konnte eure Lösungsansätze vom Ablauf her auch nachvollziehen und habe das mal wie folgt umgesetzt.

@echo off
::lmhosts.txt wird zeilenweise gelesen und so der Clientname für den nachfolgenden Ping als Variable H festgelegt
FOR /F %%H IN (client_list.txt) DO (
SET "clientname=%%H"  
IF "%%H"=="EOL" (  
GOTO :EOF
) ELSE (
::unter Verwendung von Variable H wird der Ping ausgeführt, die IP ermittelt und nachfolgend die lmhosts erstellt
ping.exe -n 1 -4 %clientname% >> temp.txt
FOR /F "tokens=2 delims=" %%G IN (temp.txt) DO @echo %%G %clientname% >> lmhosts   
::del temp.txt
)
)
:EOF

Leider habe ich weiterhin irgendwo Fehler eingebaut. Bei Ausführung öffnet sich nur kurz ein DOS Fenster und das war es dann. Ich wollte mit Hilfe von PAUSE schauen wo es hakt aber PAUSE wird nicht angenommen. Egal wo ich es einfüge. Da keine temp.txt erstellt wird, gehe ich davon aus, dass der Fehler bereits in der ersten Schleife liegen muss.

Was gibt es bezüglich der Verwendung von PAUSE zu beachten?

@Biber
Auch deinen Lösungsvorschlag habe ich getestet aber hier komme ich zu dem gleichen Ergebnis. Keine Ausgabe und PAUSE wird auch nicht angenommen.

Könnt ihr mir eine Denkhilfe geben damit ich mich an den Fehler herantasten kann.

Gruß
Mike
Member: miczar
miczar Jun 30, 2016 at 17:28:56 (UTC)
Goto Top
Ach so,
bezüglich der Klammern. Ich gehe mal davon aus, dass bei der zweiten Schleife ebenfalls Klammern eingefügt werden müssen?

Hier leigt vermutlich aber nicht der Fehler da selbst, wenn ich die zweite Schleife weg lasse und nach der ersten Schleife die Variable in eine Ausgabe umleite nix passiert

Gruß
Mike
Member: narthan
Solution narthan Jul 01, 2016 at 10:38:21 (UTC)
Goto Top
Hallo Mike,

zuerst musst du im Falle der verschachtelten Schleife die "verzögerte Erweiterung von Umgebungsvariablen" mittels

SETLOCAL EnableDelayedExpansion

aktivieren. Infolgedessen musst du nach Deklaration der Variable clientnamedurch

SET "clientname=%%h"  

die Variable mittels Ausrufezeichen verwenden, da es sich hier um eine verzögerte Erweiterung handelt. Falls du dich weiter in das Thema einlesen möchtest, gibt dazu einige Posts hier im Forum. Über die Internetsuche solltest du auch andere Seiten zu dem Thema finden. face-smile )

...(
ping -n 1 -4 !clientname!>> temp.txt
...
...DO @echo %%g !clientname!>> lmhosts.txt
...

Falls du noch weitere Fragen/Probleme hast - nur zu...

Wenn du meinen Code verwenden möchtest anstelle des schöneren von Biber, kann ich dir den fertigen Code posten. Ich habe ihn bereits mit Bsp. Dateien getestet und er funktioniert.

Gruß,
narthan
Member: miczar
miczar Jul 15, 2016 at 19:05:34 (UTC)
Goto Top
Hallo zusammen,

ich habe es leider nicht eher geschafft aber hier nun die Lösung.

Vorab noch einmal Danke für die schnelle und sachliche Hilfe bzw. Denkanstoß.

Eigentlich war die Lösung sehr einfach und nachdem ich mir das sehr gut geschriebene "Tutorial zur FOR-Schleife" auch noch einmal durchgelesen habe blieben keine Fragen mehr offen.

Ich habe es nun so umgesetzt:

@echo off
if exist LMHOSTS del LMHOSTS
setlocal enabledelayedexpansion
FOR /F %%H IN (client_list.txt) DO (
  SET "clientname=%%H"  
    IF "%%H"=="EOL" (  
  GOTO :EOF
) ELSE (
ping.exe -n 1 -4 !clientname! >> temp.txt 
FOR /F "tokens=2 delims=" %%G IN (temp.txt) DO @echo %%G !clientname! >> lmhosts  
del temp.txt
)
)
:EOF
echo Bitte LMHOSTS kontrollieren !
pause

Leider habe ich es zeitlich noch immer nicht geschafft mich mit der Lösung von Biber auseinanderzusetzen. Aber auch das werde ich beizeiten nachholen. Unter Verwendung von "setlocal enabledelayedexpansion" sollte aber auch diese Lösung hervorragend funktionieren.


Als kleine Info für Leser die eventuell vor der selben Aufgabenstellung stehen wie ich.

In meinem Fall waren zwei NICs verbaut und jedes Mal wurde eine falsche IP in die LMHOSTS eingetragen. Das betraf aber immer nur den PC auf dem das Script grade ausgeführt wurde. Das ganze ist aber ganz einfach zu lösen. Es muss nur die Reihenfolge der Netzwerkkarten in den erweiterten Einstellungen geändert werden.

Somit erkläre ich mein "Problem" für gelöst und verbleibe bis zur nächsten Unklarheit mit einem DANKE

Gruß
Mike