thecaptain
Goto Top

simple Batch - bin ich zu doof?

Hallo,

ich bin grade dabei ein Batch-Sicherungsprogramm mit Robocopy zu schreiben und teste vorher kleinere Elemente der Batch in separaten Dateien.

Jetzt stoße ich bei einem meiner Tests grade auf ein völlig unlogisches Problem: Ich führe die Batch aus, das cmd-Fenster erscheint für eine Zehntelsekunde und schließt sich gleich wieder - normalerweise ein Zeichen für irgendeinen gravierenden Syntaxfehler oder ähnliches.

Um den Fehler zu isolieren habe ich die Batch sehr vereinfacht, sehe aber keinen Fehler. Ich bin jetzt sogar so kühn zu behaupten, dass dort kein Fehler drin ist! (oho)

Könnte bitte mal einer über den Text schauen und mir sagen, ob ich was übersehen habe oder ob CMD einfach nur spinnt? Um die Funktion der Batch geht es hier vorläufig nicht, sondern nur darum, ob ich heute lieber wegen akuter Verblödung früh nach Hause gehen sollte. face-wink

@echo off

set i=
%i%=false
goto test

:test
echo ":test" aufgerufen  
echo.

if %i%==false (
 %i%=true
 rem goto test
 
 echo innerhalb if ist i immer noch = %i%
 echo muesste aber true sein! 
)

echo nach if i = %i%
pause

Content-Key: 83559

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

Printed on: June 16, 2024 at 05:06 o'clock

Member: Galamar
Galamar Mar 20, 2008 at 07:54:25 (UTC)
Goto Top
Ich würde bahaupten, dass das Problem bei
[code]
set i=
%i%=false
[/code]
liegt.

In dem Moment, in dem die Variable erstellt wird muss ihr auch ein Wert zugewiesen werden vorausgesetzt natürlich, dass nicht ich derjenige bin, der sich wegen totaler Verblödung freinehmen sollte ;)
Member: thecaptain
thecaptain Mar 20, 2008 at 08:01:14 (UTC)
Goto Top
Ich würde bahaupten, dass das Problem
bei
[code]
set i=
%i%=false
[/code]
liegt.

Hm, eigentlich sollte es dass nicht. In Automatisierte Sicherung per Robocopy - Dienst auf externe Festplatte wird das auch so gemacht.

Aber du scheinst recht zu haben: Die CMD schließt sich nicht sofort wieder - merkwürdig.

@echo off

set i=false
rem %i%=false
goto test

:test
if %i%==false (
 %i%=true
 rem goto test
 
 echo innerhalb if ist i immer noch = %i%
 echo muesste aber true sein! 
)

echo nach if i = %i%
pause

Weiß zufällig noch jemand, warum das so ist?? Außerdem zeigt er mir jetzt an "Der Befehl "false"ist entweder falsch geschrieben oder konnte nicht gefunden werden." --> HÄH??

Ich fürchte du darfst leider noch nicht ins Osterwochenende abdüsen - bei mir hingegen wird es immer wahrscheinlicher...
Member: BKAMk2
BKAMk2 Mar 20, 2008 at 08:01:15 (UTC)
Goto Top
Moin,

ich denke mal du willst eine abfrage machen, bei der "i" den standardwert "false" bekommt.
Erst wenn eine bestimmte forderung erfüllt wurde soll diese auf true springen oder?

Wenn ja, hier die lösung:
@echo off

set i=false
echo %i%
if %username%==%username% set i=true
echo %i%
if %i%==true echo Die Abfrage hat den Wert "true" ergeben!  
pause

€dit:
Nach dem von dir genannten Beispiel wird das nicht so gemacht!^^
Die Variablen werden erst gesetzt damit sie leer sind.
Danach wird ihnen ein Wert gegeben.
das ganze würde bei meiner Batch so aussehen:

@echo off

:Variablen leeren
set i=

:Variablen füllen
set i=false

:Inhalt ausgeben
echo %i%

:Abfragen und aktualisieren
if %username%==%username% set i=true

:aktuellen Inhalt ausgeben
echo %i%

:Wenn i den Wert true hat mache das hier
if %i%==true echo Die Abfrage von i hat true ergeben!

pause

Em Variablen nachträglich einen Wert zuzuordnen muss man wieder mit dem "set" befehl arbeiten. Daher auch das sofortige schliessen der cmd. Die cmd hat "false" in diesem fall wie ein befehl behandelt und gemeckert, dass dieser befehl nicht existiert

musst halt nur die jetzige "if" abfrage durch die ersetzen, die zu dem ergebnis führt was du möchtest und dann noch eine abfrage am 'Ende so gestalten wie du möchtest.

Hoffe geholfen zu haben
Member: thecaptain
thecaptain Mar 20, 2008 at 08:11:16 (UTC)
Goto Top
Nach dem von dir genannten Beispiel wird das
nicht so gemacht!^^
Die Variablen werden erst gesetzt damit sie
leer sind.
Danach wird ihnen ein Wert gegeben.

Aaaah, na sicher. Jetzt wird einiges klar. Aber warum er jetzt meint Der Befehl "false"ist entweder falsch geschrieben oder konnte nicht gefunden werden. ist mir immer noch schleierhaft.

### EDIT ###
Anmerkung am Rande:
Wenn ich bei deinem Vorschlag Copy&Paste benutze habe ich das gleiche Problem wie ganz zu Anfang: Die CMD schließt sich sofort wieder. Ich habe erst vermutet es liegt an den einfachen Doppelpunkten ( =Sprungmarken ), das scheint es aber nicht zu sein.
Member: BKAMk2
BKAMk2 Mar 20, 2008 at 08:23:11 (UTC)
Goto Top
...
Aber warum er jetzt meint Der Befehl
"false"ist entweder falsch
geschrieben oder konnte nicht gefunden
werden.
ist mir immer noch schleierhaft.

Das lag daran, dass die CMD nicht wusste was sie mit dem "false" anzufangen hat.
Dadurch das du geschrieben hast:
set i=
%i%=false

dachte die CMD die komplette zweite Zeile besteht aus Befehlen.
Den Befehl false kennt die CMD aber nicht face-wink


€dit:
Was für ein Betriebssystem hast du denn im Einsatz?

Hab Windows XP Prof. Klappt wunderbar.
Welches Beispiel hast du denn verwendet?
Member: thecaptain
thecaptain Mar 20, 2008 at 08:30:54 (UTC)
Goto Top
Das lag daran, dass die CMD nicht wusste was
sie mit dem "false" anzufangen
hat.
Dadurch das du geschrieben hast:

dachte die CMD die komplette zweite Zeile
besteht aus Befehlen.
Den Befehl false kennt die CMD aber nicht

So sieht es bei mir jetzt aus, und der Fehler kommt trotzdem:
set i=
set i=false
Wie wäre es richtig? (liegt wohl eher am OS, ich teste es gleich mal auf einer VM)
### EDIT ###
Gleicher Fehler auf WinXP home.


€dit:
Was für ein Betriebssystem hast du denn
im Einsatz?

Hab Windows XP Prof. Klappt wunderbar.
Welches Beispiel hast du denn verwendet?

1. Windows 2000 Prof. SP4
### EDIT ###
auf meiner WinXP home-VM geht es

2. Angepasst:
@echo off

::Variablen leeren
set i=

::Variablen füllen
set i=false

::Inhalt ausgeben
echo %i%

::Abfragen und aktualisieren
if %username%==%username% set i=true

::aktuellen Inhalt ausgeben
echo %i%

::Wenn i den Wert true hat mache das hier
if %i%==true echo Die Abfrage von i hat true ergeben!

pause
Member: BKAMk2
BKAMk2 Mar 20, 2008 at 08:46:35 (UTC)
Goto Top
Kann daran liegen das Win 2000 die Variable %username% nicht kennt.
Gib mal "set" in der cmd ein. (ohne "")

Darauf sollte diese dir alle verfügbaren Varaiblen anzeigen.
Such dir da eine raus.

Ansonsten hab ich keine ahnung....hab erst vor kurzem mit Batch angefangen und das auch nur auf Win XP rechnern.
Member: thecaptain
thecaptain Mar 20, 2008 at 10:28:19 (UTC)
Goto Top
Doch, kennt es. Wenn ich SET eingebe gibt es auch "USERNAME". Hatte ich schon probiert. face-wink

Wenn ich aber z.B. %username% durch %os% ersetze und weiter unten testweise ein
echo %username%
reinschreibe geht es - seltsam.

Zwar weiß ich jetzt immer noch nicht, warum er meint "false" sei ein Befehl, aber dennoch:
Hoffe geholfen zu haben
-> auf jeden Fall!

### EDIT ###
Falls es noch jemanden interessiert, wie ich überhaupt auf diesen Code-Schnipsel gekommen bin:
Ich habe mir dieses Beispiel zu Gemüte geführt und gedacht " das könnte doch auch anders gehen... ".
Member: bastla
bastla Mar 20, 2008 at 11:55:28 (UTC)
Goto Top
Hallo thecaptain und BKAMk2!

Ich habe mir dieses Beispiel zu Gemüte geführt und gedacht " das könnte doch auch anders gehen... ".
Kann es auch, aber nur bezüglich des Aktivierens der "DelayedExpansion" (der Möglichkeit, auch innerhalb von Blöcken wie "for"-Schleifen oder eben "if"-Konstrukten, Variableninhalte nicht nur verändern, sondern die geänderten Inhalte auch wieder auslesen zu können). Im verlinkten Beispiel wird dies durch den Start der CMD-Shell mit dem Argument "/v" erreicht - die Alternative dazu (findet sich auch in vielen Beispielen hier im Forum) besteht darin (meist gleich zu Beginn des Batches) folgenden Befehl zu verwenden:
setlocal enabledelayedexpansion
Daraus ergibt sich, zusammen mit dem schon standardmäßigen "@echo off" folgende "Eröffnungszeile":
@echo off & setlocal enabledelayedexpansion
Der Preis für die "verzögerte Variablenauflösung" ist die veränderte Schreibweise mit "!" anstelle von "%" und, dass in weiterer Folge "!" nicht mehr als gewöhnliches Textzeichen (zB bei Ausgabe eines Hinweises mit "echo") verwendet werden kann. Befinden sich in einem Text sogar zwei "!", wird der Teil dazwischen als Variablenname interpretiert, was dazu führt, dass er entweder verschwindet (da eine derartige Variable nicht definiert ist - zur Demo eine zusätzlich Zeile im Beispiel unten) oder sogar ein anderer Text aufscheint (falls es tatsächlich eine Variable dieses Namens bereits gäbe).

Um diesen Problemen auszuweichen, wird als Alternative zumeist ein internes Unterprogramm verwendet (Aufruf mit "call :Sprungziel", Ende mit "goto :eof" bzw Batchende).

Für den im Eröffnungsbeitrag geposteten Ansatz wären daher folgende Schreibweisen (inkl Korrektur der Variablenzuweisungen, die immer ein vorhergehendes "set" verlangen, und Absicherung der "if"-Zeile mit Anführungszeichen) möglich (die Änderung der jetzt nicht mehr zutreffenden Texte habe ich eingespart face-wink):
@echo off & setlocal enabledelayedexpansion

set i=false
goto test

:test
echo ":test" aufgerufen  
echo.

if "%i%"=="false" (  
 set i=true
 rem goto test
 
 echo innerhalb if ist i immer noch = !i!
 echo muesste aber true sein! 
 echo ... und das ist es jetzt !nicht!
)

echo nach if i = %i%
pause
oder
@echo off

set i=false
goto test

:test
echo ":test" aufgerufen  
echo.

if "%i%"=="false" call :SetzeTrue &  rem goto test  

echo nach if i = %i%
pause
goto :eof

:SetzeTrue
set i=true
  
echo innerhalb if ist i immer noch = %i%
echo muesste aber true sein! 
echo ... und das ist es jetzt !nicht!

goto :eof

Noch zwei Anmerkungen:

Das oben gezeigte "setlocal" (ohne "enabledelayedexpansion") sollte eigentlich immer verwendet werden - damit wird die Gültigkeit aller innerhalb eines Batches vorgenommenen Veränderungen an Variablen auf diesen Batch beschränkt. Bereits vor der Ausführung des Batches definierte Variable (mit "set" zu überprüfen) können aber wie gewohnt verwendet werden und "bringen ihre Werte mit".

Da "i" sehr häufig als Laufvariable einer "for"-Schleife verwendet wird, würde ich für die Funktion als Schalter eher eine Variable "Fertig" oder "OK" oÄ verwenden.


Grüße
bastla
Member: miniversum
miniversum Mar 20, 2008 at 15:39:11 (UTC)
Goto Top
So und jetzt komm noch ich hinterher wegen dem %username% Problem face-smile
Könnte es seind as dein Benutzername eine Leerstelle enthält?
Dann würde das ganze bei demCode:
if %username%==%username% set i=true
sowas machen
if Vorname Nachname==Vorname Nachname set i=true
Der Befehl wir also zerpflückt.
Ändert man das ganze gringfügig funktioniert es:
if "%username%"=="%username%" set i=true

miniversum