Batch Was läuft hier falsch?

Freut mich, dass es jetzt funktioniert, aber ich möchte noch anmerken, dass

a) es massives Verbesserungspotential gibt, weil extrem redundant geskriptet wurde
b) das eine der unübersichtlichsten Batches ist, die ich kenne
c) BATCH hier vermutlich schlicht und ergreifend das falsche Werkzeug ist, weil sich das mit anderen Skript- bzw Programmiersprachen deutlich effizienter lösen lässt.

Mit einem PowerShell- oder wsh-Script wärst du da besser beraten gewesen. Oder du hättest zumindest die ganze PC-Unterscheidungsarie in Funktionen kapseln sollen statt goto und Co so auszureizen, um dann weite Teile der PC-Fälle zu kopieren, selbst wenn sie sich durch Pfade o.ä. unterscheiden. Zur Zeit sind das über 500 Zeilen, aber mit geschickter Kapselung kann man auch so eine Batch locker auf Hälfte reduzieren ;)
Aber gut, wenn's funzt, dann funzt es. Ich will mir aber nicht vorstellen wie viel Zeit und Nerven dich das gekostet hat..
 
Zuletzt bearbeitet:
Ich wäre auch eher dafür, Funktionsblöcke mit Parametern zu schaffen, um den Umfang zu reduzieren. Die "Auswahl" des Funktionsumfanges könnte dann z.B. ein CASE-Statement übernehmen (oder SELECT). Aber zsh ist nicht gleich windows-shell, batch ist, wie wir wieder feststellen mussten, ein wenig...
...resistent.
 
Nett gemeint, aber ich hab es nunmal, wie es da alles drinsteht so gelernt.
Es ist kein Scherz wenn ich erzähle dass ich eine leichte Lernbehinderung habe durch meine Epilepsie, und ich denke ihr könnt es sicher verstehen dass man darauf stolz ist es bisher soweit geschafft zu haben ;)
 
Das war auch in keinster Weise als Angriff gemeint, sondern nur eine Einschätzung. Wenn's zB unbedingt Batch sein muss, empfehle ich, auch etwas erweiterte Konzepte mit einzubeziehen. Insbesondere bei wiederholenden Kommandos bzw Abfolgen davon.

Beispiel zur Verdeutlichung :

Code:
IF "%COMPUTERNAME%"=="A" GOTO:A
IF "%COMPUTERNAME%"=="B" GOTO:B
IF "%COMPUTERNAME%"=="C" GOTO:C
IF "%COMPUTERNAME%"=="D" GOTO:D
GOTO:EOF

:D
Befehl1 param1D
Befehl2 param2D
Befehl3 param3D
Befehl4 param4D
GOTO:POWEROFF

:C
Befehl1 param1C
Befehl2 param2C
Befehl3 param3C
Befehl4 param4C
GOTO:POWEROFF

:B
Befehl1 param1B
Befehl2 param2B
Befehl3 param3B
Befehl4 param4B
GOTO:POWEROFF

:A
Befehl1 param1A
Befehl2 param2A
Befehl3 param3A
Befehl4 param4A
GOTO:POWEROFF

:POWEROFF
shutdown /t 5
GOTO:EOF

Das hier macht genau das gleiche, aber schlanker und erweiterbar:

Code:
IF "%COMPUTERNAME%"=="A" CALL:X param1A param2A param3A param4A
IF "%COMPUTERNAME%"=="B" CALL:X param1B param2B param3B param4B
IF "%COMPUTERNAME%"=="C" CALL:X param1C param2C param3C param4C
IF "%COMPUTERNAME%"=="D" CALL:X param1D param2D param3D param4D
CALL:POWEROFF
GOTO:EOF

:X
Befehl1 %1
Befehl2 %2
Befehl3 %3
Befehl4 %4
GOTO:EOF

:POWEROFF
shutdown /t 5
GOTO:EOF

Mit CALL:SPRUNGMARKE kann man den Block an der Sprungmarke als Funktion ausführen. Das heißt nach dem CALL geht es an der ursprünglichen Stelle weiter. Wichtig ist, dass der Sprung- bzw Funktionsbereich am Ende mit GOTO:EOF wieder zurückspringen muss. In der Funktion X werden die individuellen Parameter für ABCD einfach beim Aufruf übergeben und dann in X mit %1 - %4 abgegriffen. Insbesondere wenn Befehl1-4 komplex sind, minimiert man so Fehler, weil sie nur einmal vorkommen und nicht mehrfach - also redundant - a getippt oder kopiert werden müssen. Im ersten Beispiel müsste man für E, F, G und H den kompletten Block kopieren, beim zweiten Beispiel ist es jeweils nur eine Zeile, die X mit den passenden Parametern aufruft.

Probier es einfach mal aus, just4fun. Wenn man das verinnerlicht hat, kann man mit Batch deutlich entspannter umgehen als wenn man riesige Skripte baut, die sich immer wiederholen... ;)
 
Zuletzt bearbeitet:
Hm, und wie sucht er sich dann den jeweiligen Befehl aus? Mit zum Beispiel "param2B" nimmt er das wegen Befehl2 "%2", also wegen der %2. Aber was bedeutet das "B" zum Beispiel bei "param2B" - Nur als "Name" der Zeile, oder auch für was bestimmtes?
 
Das "B" dient (wie auch das A, C und das D) zur Kenntlichmachung, daß es sich hier um einen einzigartigen Parameter handelt, nur für diese Maschine, da [[ ${Computername} = "B" ]]. Analog findest Du bei [[ ${COMPUTERNAME} = "C" ]] entsprechende Parameter mit Namen *C$.
 
Genau, das sind nur die individuellen Parameter für die Befehle, abhängig vom computernamen. Konkret könnten das beispielsweise Pfade sein, die sich von PC zu PC unterscheiden. In diesem Beispiel ist der eigentliche Ablauf je Computer identisch. Wenn dies aber nicht der Fall sein sollte - das ist bei der riesigen Batch am Smartphone nicht zu überblicken - kann man auch die Befehle kapseln oder eine Reihe von Befehlen. Du machst zB mehrmals copy und reg Export für Nvidia. Das könnte man auch als Funktion wiederverwenden.

Code:
:A
machirgendwas
CALL:BACKUPNVIDIA A
machnochmehr
GOTO:EOF

:B
machirgendwas
CALL:BACKUPAMD B
GOTO:EOF

:C
machirgendwas
CALL:BACKUPNVIDIA C
machnochmehr
GOTO:EOF

:BACKUPNVIDIA
copy irgendwas c:\nvidia\%1\
copy nochwas c:\nvidia\%1\
copy nochmehr c:\nvidia\%1\
reg export einkey c:\nvidia\%1\einkey.reg
reg export nocheinkey c:\nvidia\%1\nocheinkey.reg
reg export undnocheinkey c:\nvidia\%1\undnocheinkey.reg
GOTO:EOF

:BACKUPAMD
copy irgendwas c:\amd\%1\
copy nochwas c:\amd\%1\
copy nochmehr c:\amd\%1\
reg export einkey c:\amd\%1\einkey.reg
reg export nocheinkey c:\amd\%1\nocheinkey.reg
reg export undnocheinkey c:\amd\%1\undnocheinkey.reg
GOTO:EOF

Als weiteren Tipp rate ich dir, insbesondere lange Pfade, die du ständig wiederverwendest, in einer Variable vorzuhalten. Entweder den kompletten Pfad oder nur den Teil, der gleichbleibt. In Teilen tust du das bereits, aber man sollte alles was wiederverwendet wird kapseln. Wenn sich zB der Pfad ändert, muss man nur einmalig die Variable ändern und nicht in 500 Zeilen Suchen&Ersetzen machen.

Variablen können auch aufeinander aufbauen :

Code:
SET Sftw=D:\Eigene Dateien\Sonstiges\Scripts\2. Verbindungen und Darstellung
SET Hrdw=D:\Eigene Dateien\Sonstiges\Scripts\3. Hardware Einstellungen

SET scriptpath=D:\Eigene Dateien\Sonstiges\Scripts
SET Sftw=%scriptpath%\2. Verbindungen und Darstellung
SET Hrdw=%scriptpath%\3. Hardware Einstellungen

*edit : Nächstes Mal schreibe ich sowas am Laptop..... Puh...
 
Du hast das am Smartphone geschrieben? Masochist...

Gehen CASE-Statements? In etwa wie

Code:
case ${Computername} in
    A|a){
        machirgendwas
        CALL:BACKUPNVIDIA A
        machnochmehr
    }
    ;;
    B|b){
        machirgendwas
        CALL:BACKUPAMD B
    }
    ;;
    C|c){
        machirgendwas
        CALL:BACKUPNVIDIA A
        machnochmehr
    }
    ;;
    *){
        return 1
    }
    ;;
esac

FOR mit Arrays? In etwa so:
Code:
for PFAD in /home/user /var/log /var/mail; do
    tar -czf /mnt/smb/backup/${PFAD}_$(date +"%A--%Y%m%d%H%M%s").tar.gz ${PFAD}
done
 
Zuletzt bearbeitet:
Aaah +kreisch+ ^^ - Zu viel auf einmal ^^
Ja, das mit dem kleiner machen beobachte ich schon, aber wichtiger war mir erst, dass auch alles im Script überhaupt richtig läuft - Die erste Entstehung des Scripts ist nun auch schon ca 1 1/2 Jahre her, und es kam immer wieder was neues hinzu oder weg, da ich immer wieder was neues dazulerne. Und es ist auch nicht das einzige Script was ich "pflege". Bisher bin ich zufrieden dass es überhaupt funktioniert, und kann jetzt mal nach Kleinigkeiten der Darstellung nachschauen.
 
Manaplayer schrieb:
Aaah +kreisch+ ^^ - Zu viel auf einmal ^^

Ruhig Blut. Das war von mir eigentlich eher eine Frage an @Raijin, da ich von batch eher wenig Ahnung habe. Microsofts Version einer shell hatte ich mit Win3.11 und DOS 6.2 endgültig verlassen, seitdem bewege ich mich lieber in bash und zsh. Ist dennoch interessant, sich mal mit jemandem über die Unterschiede auszutauschen.
 
Twostone schrieb:
Gehen CASE-Statements?
Bitte was? Echt jetzt? Im Ernst? :lol:

Windows Batch ist der größte Krampf unter der Sonne. Batch vs bash ist so wie Seifenkiste vs Porsche ;)
 
Raijin schrieb:
Bitte was? Echt jetzt? Im Ernst?

Was weiß ich. Meine letzte Batch habe ich geschrieben, da war (MS-)DOS 6.2 und Windows for Workgroups das Maß aller Dinge bei Heimanwendern und mein 80486DX mit 260MB-Festplatte und 4MB RAM der letzte Schrei (und ich noch jung). Damals konnte man mit meinem "Computerwissen" auch gefühlt eine Streichholzschachtel füllen.

Mittlerweile bin ich vielleicht bei einer Kaffeekanne angekommen...
 
Zurück
Oben