Batch Script: Flag?

bandchef

Lt. Commander
Registriert
Juli 2016
Beiträge
1.493
Code:
IF NOT EXIST %PATH1% (
    echo "say something 1"
) ELSE (
    echo "Path1 exists."
)

IF NOT EXIST %PATH2%\abc (
    echo "say something 2"
) ELSE (
    echo "abc subfolder exists."
)

IF NOT EXIST %Path3%\abc.exe (
    echo "say something 3"
) ELSE (
    echo "abc.exe exists."
)

Ich möchte nun, pro if eine Variable path1_flag, path2_flag, path3_flag haben, die im Fall PathX NOT EXIST auf 1 geht. Wenn die drei ifs durch sind, soll eine if Abfrage kommen, in der Form:
IF path1_flag == 1 OR path2_flag == 1 OR path3_flag == 1 (
echo "say something"
)

Das Problem ist, das alles was ich bisher ausprobiert habe, nicht zum gewünschten Erfolg führt. Auf mich wirkt es gerade so, als ob es keine interne Rechenvariablen gibt, mit denen man solche flags umsetzen könnte...

Kann mir jemand weiterhelfen?
 
Zuletzt bearbeitet:
Eine Möglichkeit: Setze in allen else-Zweigen die selbe Variable auf 1 und in einer 4. if-Bedingung prüfst du, ob Variable == 1 ist.
 
Code:
IF NOT EXIST %PATH1% (
    echo "say something 1"
    set "path1_flag=1"
) ELSE (
    echo "Path1 exists."
    set "path1_flag="
)

IF NOT EXIST %PATH2%\abc (
    echo "say something 2"
    set "path2_flag=1"
) ELSE (
    echo "abc subfolder exists."
    set "path2_flag="
)

IF NOT EXIST %Path3%\abc.exe (
    echo "say something 3"
    set "path3_flag=1"
) ELSE (
    echo "abc.exe exists."
    set "path3_flag="
)
if "%path1_flag%"=="1" if "%path2_flag%"=="1" if "%path3_flag%"=="1" (
    echo do some creative stuff
) else (
    echo do some boring stuff
)
 
Vielen Dank für eure Vorschläge. Mein Problem ist, dass ich nicht genau weiß wie man so eine interne Rechenvariable anlegt.

Code:
set path1_flag = 1
set path1_flag = %1
set "path1_flag = 1"
set %path1_flag" = 1
 
Zeile 1+3 sind möglich. Evtl. auch Zeile 2, je nachdem, was in "%1" gespeichert ist (das ist ein übergebenes Argument beim Aufruf von Batches oder Subroutinen).

EDIT:
Die Antwort bezog sich darauf, wenn du mit "interne Rechenvariable" dann Berechnungen mit SET /A meintest.
 
Mein Code ist nun so:
Code:
IF NOT EXIST %ABC_PATH% (
    echo "ABC folder does not exist."
    set flag1=1
) ELSE (
    echo "ABC folder exists.
    set flag1=0
)

IF NOT EXIST %ABC_PATH%\abc (
    echo "abc sub folder does not exist."
    set flag2=1
) ELSE (
    echo "abc sub folder exists.
    set flag2=0
)

IF NOT EXIST %ABC_PATH%\abc.exe (
    echo "abc.exe does not exist."
    set flag3=1
) ELSE (
    echo "abc.exe exists.""
    set flag3=0
)

IF "%flag1%"=="1" if "%flag2%"=="1" if "%flag3%"=="1" (
    echo "minimum one flag was set"
) ELSE (
    echo "no flag was set"
)

Wenn nun einer der zwei Ordner oder die .exe nicht existiert, wird aber das Echo des 4. IFs nach wie vor nicht ausgegeben. Ich muss also davon ausgehen, dass entweder die sets nicht funktionieren, oder die 4. if abfrage nicht.
 
Zeile 25 kommt mir komisch vor (mit den 3 IFs hintereinander ohne logische Verknüpfung, aber das hatte @mae1cum77 auch so geschrieben).

Statt flag1, flag2, flag3 nutze einfach nur flag.
Du willst doch nur wissen, ob eines davon zutrifft, welches davon ist jedoch egal. Und Zeilen 6, 14, 22 können komplett weg.

Zeile 25 wäre dann nur noch
Code:
IF "%flag%"=="1" (
 
Das Konstrukt mit den 3 (oder mehr) IFs in einer einzigen Zeile habe ich bisher nicht verwendet. Aber es wird wohl wie verschachtelte IF-Schleifen funktionieren, d.h. das ECHO wird nur angezeigt, wenn das 3. IF erreicht wird. Ist also Flag1=0 oder Flag2=0, dann wird das 3. IF und dessen ECHO nicht erreicht.
 
Ha, super. Jetzt geht's.
Ergänzung ()

Darkman.X schrieb:
Ist also Flag1=0 oder Flag2=0, dann wird das 3. IF und dessen ECHO nicht erreicht.
Einen OR oder AND Operator gibt es nicht? Dann wäre das Problem des Missverstehens gar nicht gegeben.
 
Wirklich? Denn der Text "minimum one flag was set" wird so nicht mehr funktionieren / macht keinen Sinn. Denn wenn in der 3. IF NOT EXIST-Abfrage (Zeile 17) ein Flag=0 gesetzt wird, dann erkennt die IF-Abfrage in Zeile 25 (umgebaut mit "Flag" statt "Flag1", "Flag2", usw.) nicht, dass in den vorherigen IF-Abfragen das Flag temporär gleich 1 war.
Ergänzung ()

bandchef schrieb:
Einen OR oder AND Operator gibt es nicht? Dann wäre das Problem des Missverstehens gar nicht gegeben.
Es kommt darauf an, was du genau möchtest. Du hattest ja schon "interne Rechenvariable" erwähnt. Damit könnte man z.B. arbeiten, wenn dir egal ist, welches und wieviele Flags=1 waren.

Bezugnehmend auf #6:
In eine Zeile 0 ein SET Flag=0 setzen.
In den Zeilen 3, 11 und 19 ein SET /A Flag+=1 setzen.
In Zeile 25 dann ein IF %Flag% GTR 0 ( setzen.
 
Zuletzt bearbeitet: (Schlechte Wortwahl von mir :( -> "Es gibt keine if-Schleifen, sondern nur if-Abfragen")
  • Gefällt mir
Reaktionen: mae1cum77
bandchef schrieb:
Einen OR oder AND Operator gibt es nicht?
Windows Batch ist nicht wirklich eine Skript- oder gar Programmiersprache. Batch kommt von "Stapelverarbeitung" und das muss man gewissermaßen wörtlich nehmen. Batch ist weitestgehend nur für das gestapelte Nacheinanderausführen von Kommandos gedacht. Es gibt zwar einige halbwegs komplexe Konstrukte wie if und for, aber sie funktionieren aufgrund des Befehlinterpreters nicht unbedingt so wie man denkt.

Je nachdem was das fertige Skript am Ende tun soll, könnte man das eventuell auch etwas kürzer machen:
(Betonung liegt auf könnte, da man sowas anhand unspezifischer Code-Snippets nicht beurteilen kann)

Code:
IF NOT EXIST %pfad1% SET fehler=1&GOTO:FEHLER
IF NOT EXIST %pfad2% SET fehler=2&GOTO:FEHLER
IF NOT EXIST %pfad3% SET fehler=3&GOTO:FEHLER

ECHO Das Skript ist gerade schwer am Arbeiten

GOTO:EOF


:FEHLER
ECHO Pfade fehlerhaft %fehler%
GOTO:EOF

Beim ersten Pfad, der nicht existiert, geht das Skript in den Fehlermodus. Dabei setzt es fehler auf die entsprechende Nummer, die man im FEHLER-Block auslesen kann - gesetzt den Fall das ist überhaupt notwendig. Wenn nicht, lässt man bei den IFs das SET einfach weg (inkl. &) und macht nur das GOTO.
 
  • Gefällt mir
Reaktionen: bandchef und mae1cum77
Darkman.X schrieb:
Wirklich? Denn der Text "minimum one flag was set" wird so nicht mehr funktionieren / macht keinen Sinn.
Mit Beitrag von kartoffelpü und diversen umbauten des Codes von mir, den ich aber nicht (mehr) gepostet habe, funktioniert es nun so wie gewünscht.
kartoffelpü schrieb:
Zeile 25 kommt mir komisch vor (mit den 3 IFs hintereinander ohne logische Verknüpfung, aber das hatte @mae1cum77 auch so geschrieben).

Statt flag1, flag2, flag3 nutze einfach nur flag.
Du willst doch nur wissen, ob eines davon zutrifft, welches davon ist jedoch egal. Und Zeilen 6, 14, 22 können komplett weg.

Zeile 25 wäre dann nur noch
Code:
IF "%flag%"=="1" (
Vielen Dank dafür.


Eine weitere Frage habe ich noch:
Wenn ich die Batch starte, dann bekomme ich in der Konsole eine Ausgabe, die folgendermaßen lautet:
Could not find d:\folder\subfolder1\subfolder2\subfolder3\subfolder4\-f

Verstehe ich es richtig, dass er nach einem Subfolder "-f" sucht, den aber nicht findet? Oder ist "-f" irgendein Batch-Option/Schalter? Zu -f an sich hab ich jedenfalls nichts gefunden.
 
bandchef schrieb:
Verstehe ich es richtig, dass er nach einem Subfolder "-f" sucht, den aber nicht findet?
Ja, aber:

bandchef schrieb:
Mit Beitrag von kartoffelpü und diversen umbauten des Codes von mir, den ich aber nicht (mehr) gepostet habe, funktioniert es nun so wie gewünscht.
Wenn du den Code, der zu dieser Meldung führt, nicht postest, kann man dazu auch nichts weiter sagen.
 
  • Gefällt mir
Reaktionen: Incanus
Poste doch den ganzen Code oder ist da etwas geheimes dran? Wenn er zu lang ist, kannst du ihn im Spoiler-Tag einklappen.

Code:
@ECHO OFF
...

Generell muss man Batch-Dateien etwas anders debuggen als man es von herkömmlichen Skripten oder gar Hochsprachen gewöhnt ist. Um zahlreiche Echos an diversen Stellen kommt man nicht drumherum, um beispielsweise die Inhalte von Variablen oder die Pfade durch IF und Co verfolgen will.
 
Die Frage die ich mir stelle, muss es unbedingt Batch sein. Gefühlt kann man das bestimmt in Powershell eleganter lösen?
 
So, nun hab ich's gefunden. Die Stelle ist:
Code:
    del -f !TMP_ABC_BIN!
    del -f !TMP_ABC_SHIFTED!

Was macht del -f? Ich denke, das ist das Problem.

Den gesamten Code posten wäre natürlich das Beste, da es sich aber um Firmencode handelt bin ich mir nicht so sicher, ob ich das tun sollte.


Hier ist auch noch was, was ich jetzt nicht so versteh:
Code:
for %%i IN (!INPUT_ABC_S19!) do set INPUT_ABC_S19_FILENAME=%%~nxi

Das ist anscheinend eine for-loop. Aber was macht sie?
Ergänzung ()

Mystery1988 schrieb:
Die Frage die ich mir stelle, muss es unbedingt Batch sein. Gefühlt kann man das bestimmt in Powershell eleganter lösen?
Das könnte man sicherlich viel besser und schneller mit was anderem lösen, soll ich aber nicht.
 
Mystery1988 schrieb:
Die Frage die ich mir stelle, muss es unbedingt Batch sein.
Die Frage muss man sich bei Batch immer stellen.
Wie ich immer zu sagen pflege: Batch is a Bitch!

PowerShell ist deutlich mächtiger, aber die Berührungsängste sind meist größer, weil PowerShell mehr nach "programmieren" aussieht. Das ist aber eher ein Vor- als ein Nachteil, weil es dadurch klaren Regeln folgt und einen großen Werkzeugkoffer mitbringt, während Batch fast nur aus Workarounds und Sonderfällen besteht, um den Mangel an Werkzeug auszugleichen - zB sowas banales wie eine .ToUpperCase() Funktion........

bandchef schrieb:
Was macht del -f?
Nicht das, was man denken sollte, weil Parameter-Switches unter Windows in der Regel mit / beginnen und nicht mit -
Gib in der Kommandozeile mal del /? ein und du wirst sehen was -f tun sollte und wie es stattdessen aussehen muss, nämlich /f ;)

bandchef schrieb:
Das ist anscheinend eine for-loop. Aber was macht sie?
Ohne sie ausprobiert zu haben würde ich meinen, dass der Dateipfad INPUT_ABC_S19 durchsucht wird und der Dateiname inkl. Erweiterung ausgelesen wird.

Wie ich schon schrieb, debugging läuft in Batch nur mit Echos. Wenn du nicht weißt was wie wo passiert, bau echos ein. Du könntest beispielsweise nach dieser Schleife dieses Echo setzen:

echo "!INPUT_ABC_S19!" "!INPUT_ABC_S19_FILENAME!"

Dann siehst du was in die Schleife reingeht und was sie ausspuckt.
 
  • Gefällt mir
Reaktionen: kartoffelpü
Das echo hat mir weitergeholfen.

Noch eine Frage:

Was macht

Code:
!ABC_PATH!\abc.exe -if=%ABC_FOLDER%\ABCS_CAL\%PROJECTIDENTIFIER%-%NR%-%VER%-%PROJECT%_%SUB%_%Deliver%.s19 -of=%ENCR%\%PROJECTIDENTIFIER%-%NR%-%VER%-%PROJECT%_%SUB%_%DELIVERY%.s19 -kf=%ABC_KEY_PATH%\ABC_KeyValue.xml >> %LOG_DIR%\log.log 2>&1

Speziell das -if, -of, -kf Ich glaube das schreibt die Datei log.log ins Log Verzeichnis?
 
bandchef schrieb:
Das wirst du der Dokumentation der "abc.exe" entnehmen müssen. -if, -of und -kf sind Parameter dieser speziellen exe-Datei.

-if könnte beispielsweise für input-file stehen, -of für output-file und -kf für key-file.

Lediglich der Part ab >> gehört wieder zu batch (bzw. cmd) und leitet die Ausgabe der abc.exe in die Datei log.log um anstatt sie im Fenster anzuzeigen. 2>&1 heißt nur, dass dort sowohl stout (=normale Ausgabe) wie auch stderr (=Fehlermeldungen) landen sollen. Lässt man das weg, landen nämlich nur die normalen Ausgaben in der Datei und Fehlermeldungen gehen verloren.
 
Zurück
Oben