Workshop Batch for Runaways - Part II - Ein bisschen Handwerkszeug
Fortsetzung vom Workshop Batch for Runaways - Part I - Beispiel FindLongPath.Bat Bedenklich lange Pfade finden
To be cont'd....
Weiter gehts mit dem kleinen Batch-for-Runaways-Workshop.
Ich werde den Aufbau vom Teil 1 beibehalten: ein paar Grundlagen, viel Prosa und das Posten von ein oder zwei im Admin-Alltag verwendbaren Utilities.
Und natürlich noch ein paar erläuternde Worte zu dem Bätchelchen "FindLongPath.bat" vom letzten Mal.
Fangen wir mal auf dem Acker an, bei den Grundlagen, wer will zumindest..
Vollzieht folgenden Batch in Gedanken nach...
:NewbieStuff
CMD-Befehle vom Prompt und in der Batch-Datei: ein paar Unterschiede..
Die CMD.exe ist ein Befehls-Interpreter. Das heißt, Zeile für Zeile wird nacheinander abgearbeitet, Syntaxfehler also auch erst dann "gemerkt", wenn versucht wird, eine Zeile auszuführen. Und der CMD-Interpreter bietet von Haus aus
- NICHT die Möglichkeit eines Syntaxchecks VOR der Ausführung,
- NICHT die Möglichkeit, ein Batchprogramm Schritt für Schritt ablaufen zu lassen
- NICHT die Möglichkeit, Variableninhalte zwischendurch anzuzeigen
Warum erzähl ich solche Trivialitäten? Damit klar wird, wieviel Zeit man/frau sparen kann, wenn ein paar Tipp-/Denk-/Syntaxfehler gar nicht erst gemacht werden... und dazu muss eben einmal der geneigte Leser verstehen, was der CMD-Interpreter versteht und was nicht. Oder, um mal ein Wortspiel zu versuchen, ich darf dem Interpreter keinen Interpretationsspielraum lassen.
Mal das wichtigste Handwerkszeug:
a) Variablen ansprechen: in %-Zeichen setzen (echo %username%).
Weder CMD-Befehle noch Variablennamen sind Case-sensitiv (Ausnahme FOR..IN..DO-Zähl-Variablen).
Vollkommen gleichbedeutend sind also "echo %username%" und "Echo %UserName%" und ECHO %USERNAME%"
b) Zählvariablen in FOR..IN..DO-Schleifen: ein %-Zeichen vom Prompt aus (%i), zwei im Batch (%%i). Zählvariablen sind Case-sensitiv ( %%a ist ungleich %%A ).
c) ob eine Variable definiert ist oder nicht, läßt sich (Achtung, dürfte einigen neu sein) sowohl vom Prompt aus wie im Batch mit "if defined Variable" feststellen.
Fällt unter die Rubrik kleine Kuriositäten. (Beispiel mit undefinierter Variable test123)
[im Batch] if [%Test123%]== (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis) Test123 ist nicht definiert.
[am Prompt]>if [%Test123%]== (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis)Test123 hat Wert %test123% *nanu? Kopfkratz*
[Prompt und Batch] if NOT defined test123 (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis)"Test123" ist nicht definiert
d) Für Variablen gibt es auch eine (abschreckend aussehende) Substringfunktion (echo %path:~0,20% liefert die ersten zwanzig Zeichen der Variablen %path% - von Zeichen 0 in der Länge 20) und auch eine Suchen/Ersetzen Funktion (set test=Müller; set test=%test:ü=ue% Ergebnis: test=Mueller)
e) Bei Vergleichen mit den Operatoren (==, NEQ, GTR,...) muss immer auf beiden Seiten des Operatoren etwas stehen, sonst gibt es einen "Syntaxfehler". Zu recht natürlich.
Also im Batch nie prüfen
if %username%==Fritz goto :FritzensStuff ....sondern
if (%username%)==(Fritz) goto :FritzensStuff ..oder...if [%username%]==[Fritz] goto :FritzensStuff
Warum? Wenn %username% nicht definiert ist, wird die erste Variante aufgelöst zu
"if ==Fritz goto :FritzensStuff" und das liefert...ja genau...*gg
Außerdem könnte ich die If-Test123-Zeile oben sonst auch gar nicht formulieren: if [%Test123%]== goto... ohne Anfü-oder -Zeichen.
Das könnte nicht mal ich interpretieren, geschweige denn so ein doofer M$-Interpreter *gg
f) das Ausgabe-Umleiten... ist oft sinnvoll in Batchdateien. Viele Befehle liefern ja eine Rückmeldung auf den Bildschirm, die ich aber im Batch gar nicht lesen oder an ein anderes Programm lieber eine Protokoll-Datei übergeben will. Eine Ausgabe kann ich also zum Beispiel
- in eine Datei umleiten mit den Zeichen ">" (umleiten, Datei neu anlegen) und ">>" (falls Ziel-Datei vorhanden, anhängen),
- eine der häufigsten Batch-Umleitungen ist das Umleiten ins Nirwana ) ">nul" ."dir >nul" bedeutet also: Kommando "Dir" ausführen und den Output nicht anzeigen. Nicht sinnvoll? Abwarten...
- mit "|" den Output einer Anweisung als Input für die nächste Anweisung verwenden oder
- mit "<" aus einer Quelle lesen
Weitgehend unbemerkt bleibt allerdings, dass Bildschirm-Rückmeldungen durchaus differenziert zurückgegeben werden, nämlich als "normale" Meldungen auf den Bildschirm alias STDOUT (oder 1) und als Fehlermeldungen auf STDERR (oder 2),
Beispiel gefällig?
Wie zu sehen ist, ist die Meldung "Datei nicht gefunden" eine Fehlermeldung (auf STDERR oder 2), die auch zu sehen ist, wenn ich die normale Bildschirmausgabe unterdrücke. Die muss/kann ich gesondert umleiten.
g) die Prüfung eines ERRORLEVEL ist oft nützlich, sollte man/frau kennen beim Bätche-Bauen.
Kurzgefasst: (fast) jedes Programm/jede CMD-Anweisung gibt einen numerischen ERRORLEVEL-Wert zurück, aus dem sich Erfolg (=0) oder Fehler (1-255) ablesen lassen. Und je nach Erfolg oder Fehler eines Befehls können natürlich unterschiedliche Aktionen in einem Batch folgen.
Beispiel: ">dir /b *.lod>nul 2>nul" liefert ein Errorlevel größer 0, weil, ja ein Fehler aufgetreten ist.
Ein "echo Errorlevel vom letzten Befehl ist: %ERRORLEVEL%" liefert "Errorlevel vom letzten Befehl ist 1"
i) wenn ich im Batch indirekt andere Anweisungen ausführen lasse, muss ich deren Parameter/Umleitungen unter Umständen im Batch mit ^ "maskieren" (Beispiel folgt weiter unten...beim P.S.)
j) das Allerwichtigste (nicht hauen jetzt): zu jedem CMD-Befehl gibt es Hilfe vom CMD-Prompt aus (ECHO /? oder FOR /? oder SET /? oder einfach HELP for alles)
Zurück zur Praxis.Wir fangen mal mit am CMD-Prompt an, da, wo wir letztes Mal aufgehört haben, bei SET, %variablen%, ECHO. FOR... IN ..DO". Alle Zeilen, die mit einem ">" anfangen, sollen eine Eingabe am CMD-Prompt bedeuten. Ach ja, wer noch den Standardprompt hat, sollte den mal anpassen zum besseren Arbeiten, passt zum Thema Variablen.
Ein bisschen Platz zum Eintippen sollte schon da sein. Wenn der Eingabeprompt schon so ähnlich aussieht wie "D:\Dokumente und Einstellungen\DerBiberAusBremen>" macht es keinen Spaß, etwas einzutippen. Schaffen wir uns Platz ohne Informationsverlust.
:AdvancedStuff
<Ausgangssituation
..gibt gleich eine kleine Aufgabe dazu.
Abfrage der Variablen "prompt"
Alles klar? Die Variable %prompt% kann definert sein oder auch nicht, bevor der erste Minibatch startet.
Kleine Workshop-HausAufgabe
Ich möchte gern einen zweizeiligen Prompt haben, dort, wo ich tippe, soll nur ein ">"-Zeichen am Beginn der Zeile stehen. Was bisher im Prompt stand (LW/Pfad etc) soll in die Zeile darüber.
Tipp1: siehe bei ">Prompt /?" .. eine neue Zeile beginnen mit "$_", ein Größer-Zeichen in den Prompt einbauen mit "$g" oder (auf Deutsch) ich möchte, dass die Variable %prompt% mit "$_$g" endet.
Ach ja, aber nur, wenn der %prompt% bisher noch keinen Zeilenumbruch beeinhaltet. Sollte im Prompt schon ein Zeilenunbruch enthalten sein, diesen durch ein Leerzeichen ersetzen.
Tipp2: sollte die Variable %Prompt& noch nicht definert sein, wird sie von Windows als "$p$g" angenommen.
Macht doch mal mit dem gelesenen ( vor allem die Punkte b) und c)) einen ChangePrompt.bat, Editor aufrufen, eintippen, speichern, und starten. Bin gespannt auf die Lösungen.
Für heute soll reichen: Die Variable %prompt% ändern auf zweizeilig geht mit $_
Wer das dauerhaft bei jedem Öffnen eines CMD-Prompts haben möchte, muss eine Benutzervariable Prompt definieren unter Start->Einstellungen, System->Erweitert->Umgebungsvariablen
:GuruStuff
Okay, ich versuch mal ein paar Möglichkeiten auzuzeigen, die beim Rumbätcheln so möglich sind.
Ich wollte ja ein paar Worte zu dem FindLongPath.bat aus dem Teil 1 des kleinen Workshops sagen.
Dazu wäre es sinnvoll, diesen Batch nochmal hier zu posten, aber mit Zeilennummern. Ist einfacher.
Hmm..soll ich sowas zu Fuß machen, Copy & Paste und dann Zeilennummern eingeben? Wer bin ich denn?
Das lass ich mal ein 20-Zeilen-Bätchelchen machen, dieses hier:
der beim Aufruf von "NumberMe NumberMe.bat" sich selbst so aufbereitet:
Nun kann ich ziemlich einfach Kommentare schreiben. Mach ich auch.
ad 02: Zwei Befehle in einer Zeile mit & hatte ich schon erwähnt, SETLOCAL EnableDelayedExpansion noch nicht. Siehe dazu bitte die Hilfe bei Setlocal /?
ad 06 Da schwächelt mein Batch...Umlaute gehen verloren. Hätte ich euch auch verschweigen können. Mach ich in der nächsten Version weg. *gg
ad 07 Parameter fehlt? Dann die richtige Syntax anzeigen. Ist guter Stil IMHO.
Fehlermeldung bei Aufruf ">NumberMe" wird expandiert zu: "Syntaxfehler: NumberMe InDatei [OutDatei] [/n:Breite Num.]"
ad 08 Angegebene Datei nicht gefunden. Sollte der Benutzer wissen. Fehlermeldung bei Eingabe ">NumberMe num" wird expandiert zu "Fehler NumberMe: InDatei "num" nicht gefunden."
ad 09 Hier setze ich meine beiden Variablen pOutput und pN erst auf Befault, dann auf das, was der Anwender will.Und zwar mit "call SetParameter %1". Ein "call :xx" wird ausgefüht bis zu einem "goto :eof und kehrt dann zurück. Schaun wir mal, was da passiert.
ad 16 Da springt der "Call" also hin
ad 17 den Parameter, z.b. "con:" oder "/n:2" mal eben zwischenspeichern in Variable pX
ad 18 Prüfen, ob die ersten 3 Stellen="/n" sind, wenn ja und ein numWert folgt, setzen von pN als Zahl bzw.
wenn Nicht die ersten 3 Stellen ="/n" sind und ein numWert folgt, setzen von pOutputmit diesem Parameter
ad 19 Entspricht einem "Return" ..zurück zu Zeile 09
ad 10 Falls die eine Outputdatei angegeben ist und eine alte Version existiert, diese löschen. Aber Bildschirm nich löschen *gg
ad 11 Die Variable "line" brauche ich, um Zeilennummern anzuzeigen. bzw die letzten Stellen pN Stellen davon. Okay, okay, ich gehe in der Praxis davon aus, das nur 2 bis 4 Stellen realistisch sind. Wer damit Texte nit mehr als 9999 Zeilen "nummerieren" will, sollte noch ein paar Nullen dranhängen.
ad 12-14 eine FOR.. IN ..DO -Schleife über mehrere Zeilen. Geht, wenn es geklammert wird.
ad 13 13 ist eine Unglückszahl.14 auch.Hier hat der Aufruf von "NumberMe NumberMe.bat dazu geführt, dass der CMD-Interpreter den Text in der Inputdatei teilweise auflöst,
Eine der lustigen Kuriosiäten des CMD-Interpreters, die man nur bemerkt, wenn man/frau mal Batchdateien mit mehr als 10 Zeilen zu schreiben versucht. Ein Seiteneffekt dieser vom M$ halbherzig implementierten "SETLOCAL EnableDelayedExpansion"-Mimik ist, das alles, was zwischen zwei Anführungszeichen steht, als sofort aufzulösende Variable abgesehen wird. Seiteneffekt im richtigen Leben:
Na ja, an solche solche Sachen wie CMD-Interpreter werde bei M$ sicher auch nur Praktikanten gesetzt.
Variable %line% wird hier auflöst wird zur Zahl 10013...Shit happens. Eigentlich steht hier "set /a line=!line!+1" .Was bedeutet, zähle die %line% um 1 hoch und mach das SOFORT. Grund: der CMD-Interpreter hat ja schon die ganze FOR-Anweisung gelesen und überall schon %line% durch den Wert von %line% ersetzt. Ich will aber den Wert von %line innerhalb der Anweisung verändern.
ad 14 Eigentliche Zeile: "echo !line:~-%pN%! %%i >>%pOutput%". Siehe ad 13). Okay, den meisten von Euch wellen sich die Fussnägel bei so einer Zeile, aber ich kanns erklären..*gg. Was ich hier will (und auch tue) ist, eine Zeile der Form "nn TextblablaBlubb" in eine Datei %pOutput" anzuhängen. Der "TextblablaBlubb" steht in %%i. Und die Zeilennummer bilde ich aus den letzten Stellen der %line%-Variablen, die in dieser Zeile den Wert 10014 hat. Jetzt klar?
%line% ist 10014; %line:~-2% wäre dann der Substring von 10014, die letzten 2 Stellen.
Und die Zahl 2 hole ich aus der Variablen %pN%.
Okay, mal sehen, ob jetzt noch was zum FindLongPath.bat zu sagen bleibt.
Dessen Aufbereitung sieht so aus (Zeile 14 und 50 nachbearbeitet):
ad 22, 32, 35 und 58 ja,ja.. die Umlaute gehen kaputt...nicht nur meine Schuld... Greeeezz @m$
Konsequenz: Umlaute sparsam verwenden in Batches - auch im Jahr 2005 und bei 64-Bit-Architekturen!
ad 04 @echo off & SETLOCAL ENABLEEXTENSIONS ... EnableExtensions ist Standard bei W2k-XP. Hätte ich mir schenken können, Dann wäre es kürzer geworden.
ad 05 Brauche ich für nur meine Pseudo-Debug-Mimik. Wäre sonst auch überflüssig.
ad 06 Eine meine Standardzeilen in Batches (per Copy & Paste). Damit kann ich Batches Zeilen einbauen, die im Normalbetrieb als Kommentar interpretiert werden, Wenn ich eine Variable "DebugMyBatches" vor dem Start der Batchdatei gesetzt habe, werden aus den "REM "-Kommentarzeilen Echo und Pause.Anweisungen.
Ach ja, geschwindelt war letztes Mal, dass ihr "Set DebugMyBatches=42" eingeben müsst. "Set DebugMyBatches=41" hätte auch gereicht.
ad 08 springt zu :ParamCheck in Zeile 36...ich jetzt auch
ad 37-38 Defaults bzw userdefininierte Parameter setzen
ad 39-40 Setze Wert von %p1masked% auf p1 (Laufwerk/Pfad), ersetze alle ":" und "\" durch "$" und "_"
ad 41 im Normalbetrieb Kommentarzeile, Im Debugmodus (%DebugMyBatches% gesetzt) eine Echo-Zeile
ad 42-43 Nix besonderes, außer.. dass sich statt SET VAR=wert auch SET "VAR=wert" schreiben lässt. Braucht man manchmal.
ad 44 Na klar, wer mitgelesen hat...ich hätte auch als Zeile 06a schreiben können :
if Defined DebugMyBatches (set "CALL_SHOW_VARS_D=call :Debugshow_vars") else set CALL_SHOW_VARS_D=REM
und Zeile 44 ändern auf %CALL_SHOW_VARS_D% "Nach Var-Setzen" ...da wäre der Batch im Normalbetrieb schneller. *gg ....aber im DebugMode Sprung zu 47-54
ad 52 Da hatte ich zuerst ein %PAUSE_D% stehen...aber ist ja Unsinn. Da kommt er nur im Debugmodus hin.
Bugfix 58 und 60 siehe unten, Posting und Fix von JohnnyB
ad 45 und Return To Caller...zurück zu Zeile 08...ganz ans Ende davon..
ad 10 Alle Verzeichnisse z'amsammeln in einer Textdatei..
ad 12 SET /a p2=%p2%-1 ..an ja, nicht ganz sauber.. Richtig wäre gewesen: SET /a p3=%p2%-1, aber ich wollte keine zusätzliche Variable p3 definieren und habe %p2% um eins gemindert, weil ich das später als Substring-Parameter brauche. Geschlampt. Aber is ja auch nur 'n Batch. *trotzdem schäm*
ad 13 SETLOCAL EnableDelayedExpansion... kennt ihr ja jetzt
ad 14 FOR /F "delims=" %%i in (%tmpdatei%) do ....mit allen Zeilen der %tmpdatei%
(set "x=%%i") && ...... jede Zeile in Variable x speichern und dann...
if "!x:~%p2%,10!" GTR "@" ... und alle Zeilen mit Substring(p2, 10) größer ist als "@"
@echo %%i >>%reportdatei% ... in die Reportdatei anhängen.
ad 15-23 Nix Aufregendes
ad 24 ENDLOCAL ist die Klammerzu zu Zeile 13.
ad 25 siehe ad 44
ad 26 alte Gewohnheiten..nach dem Variablen definieren auch wieder alle löschen.
27 GOTO :eof ...Hier nun wirklich ein Return. Gehe zum Ende der Welt. Bzw. des Batches.
So, ein bisschen was hebe ich mir noch für den nächsten Teil des Workshops auf.
Für heute noch eine kleine Kuriosität zun FOR...IN..DO -Befehl.
Laut Dokumentation sind als Zählvariablen erlaubt %a...bis %z und %A..bis %Z.
Also müsste doch folgende Anweisung einen Syntaxfehler melden:
Probierts aus Auch gern mit "FOR %! IN...DO".
Frank / der Biber aus Bremen
P.S. Für alle, die nur mitgelesen haben wegen der versprochenen GetIP.Bat's ...nächstes Mal.
Na gut, einen letzten Oneliner noch ...
Weiter geht es hier:
Workshop Batch for Runaways - Part III - Datums- und Zeitvariablen im Batch
...und immer passend zum Workshop:
Tutorial zur FOR-Schleife von Friemler
To be cont'd....
Weiter gehts mit dem kleinen Batch-for-Runaways-Workshop.
Ich werde den Aufbau vom Teil 1 beibehalten: ein paar Grundlagen, viel Prosa und das Posten von ein oder zwei im Admin-Alltag verwendbaren Utilities.
Und natürlich noch ein paar erläuternde Worte zu dem Bätchelchen "FindLongPath.bat" vom letzten Mal.
Fangen wir mal auf dem Acker an, bei den Grundlagen, wer will zumindest..
Vollzieht folgenden Batch in Gedanken nach...
::---- snipp Intro-Workshop2.bat
@echo off
Set /p Leser="Deine Kenntnisse an Batch-Know-How? K=Klein, M= Mittel G=Groß? "
If /i "%Leser%"=="K" (set Leser=Newbie) && Rem if /i bedeutet ohne Klein/Großschreibung vergleichen
If /i "%Leser%"=="M" set Leser=Advanced
If /i "%Leser%"=="G" set Leser=Guru
for %i in (Newbie Advanced Guru) do If (%Leser%)==(%i) goto %Leser%Stuff
Rem Benutzer hat nur ENTER oder weder K noch M noch G gedrückt..naja, dann nicht
(Echo Danke fürs Reinschauen!) & goto :eof
::------ snapp Intro-Workshop2.bat
CMD-Befehle vom Prompt und in der Batch-Datei: ein paar Unterschiede..
Die CMD.exe ist ein Befehls-Interpreter. Das heißt, Zeile für Zeile wird nacheinander abgearbeitet, Syntaxfehler also auch erst dann "gemerkt", wenn versucht wird, eine Zeile auszuführen. Und der CMD-Interpreter bietet von Haus aus
- NICHT die Möglichkeit eines Syntaxchecks VOR der Ausführung,
- NICHT die Möglichkeit, ein Batchprogramm Schritt für Schritt ablaufen zu lassen
- NICHT die Möglichkeit, Variableninhalte zwischendurch anzuzeigen
Warum erzähl ich solche Trivialitäten? Damit klar wird, wieviel Zeit man/frau sparen kann, wenn ein paar Tipp-/Denk-/Syntaxfehler gar nicht erst gemacht werden... und dazu muss eben einmal der geneigte Leser verstehen, was der CMD-Interpreter versteht und was nicht. Oder, um mal ein Wortspiel zu versuchen, ich darf dem Interpreter keinen Interpretationsspielraum lassen.
Mal das wichtigste Handwerkszeug:
a) Variablen ansprechen: in %-Zeichen setzen (echo %username%).
Weder CMD-Befehle noch Variablennamen sind Case-sensitiv (Ausnahme FOR..IN..DO-Zähl-Variablen).
Vollkommen gleichbedeutend sind also "echo %username%" und "Echo %UserName%" und ECHO %USERNAME%"
b) Zählvariablen in FOR..IN..DO-Schleifen: ein %-Zeichen vom Prompt aus (%i), zwei im Batch (%%i). Zählvariablen sind Case-sensitiv ( %%a ist ungleich %%A ).
c) ob eine Variable definiert ist oder nicht, läßt sich (Achtung, dürfte einigen neu sein) sowohl vom Prompt aus wie im Batch mit "if defined Variable" feststellen.
Fällt unter die Rubrik kleine Kuriositäten. (Beispiel mit undefinierter Variable test123)
[im Batch] if [%Test123%]== (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis) Test123 ist nicht definiert.
[am Prompt]>if [%Test123%]== (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis)Test123 hat Wert %test123% *nanu? Kopfkratz*
[Prompt und Batch] if NOT defined test123 (echo "Test123" ist nicht definiert) ELSE echo Test123 hat Wert %test123%
(Ergebnis)"Test123" ist nicht definiert
d) Für Variablen gibt es auch eine (abschreckend aussehende) Substringfunktion (echo %path:~0,20% liefert die ersten zwanzig Zeichen der Variablen %path% - von Zeichen 0 in der Länge 20) und auch eine Suchen/Ersetzen Funktion (set test=Müller; set test=%test:ü=ue% Ergebnis: test=Mueller)
e) Bei Vergleichen mit den Operatoren (==, NEQ, GTR,...) muss immer auf beiden Seiten des Operatoren etwas stehen, sonst gibt es einen "Syntaxfehler". Zu recht natürlich.
Also im Batch nie prüfen
if %username%==Fritz goto :FritzensStuff ....sondern
if (%username%)==(Fritz) goto :FritzensStuff ..oder...if [%username%]==[Fritz] goto :FritzensStuff
Warum? Wenn %username% nicht definiert ist, wird die erste Variante aufgelöst zu
"if ==Fritz goto :FritzensStuff" und das liefert...ja genau...*gg
Außerdem könnte ich die If-Test123-Zeile oben sonst auch gar nicht formulieren: if [%Test123%]== goto... ohne Anfü-oder -Zeichen.
Das könnte nicht mal ich interpretieren, geschweige denn so ein doofer M$-Interpreter *gg
f) das Ausgabe-Umleiten... ist oft sinnvoll in Batchdateien. Viele Befehle liefern ja eine Rückmeldung auf den Bildschirm, die ich aber im Batch gar nicht lesen oder an ein anderes Programm lieber eine Protokoll-Datei übergeben will. Eine Ausgabe kann ich also zum Beispiel
- in eine Datei umleiten mit den Zeichen ">" (umleiten, Datei neu anlegen) und ">>" (falls Ziel-Datei vorhanden, anhängen),
- eine der häufigsten Batch-Umleitungen ist das Umleiten ins Nirwana ) ">nul" ."dir >nul" bedeutet also: Kommando "Dir" ausführen und den Output nicht anzeigen. Nicht sinnvoll? Abwarten...
- mit "|" den Output einer Anweisung als Input für die nächste Anweisung verwenden oder
- mit "<" aus einer Quelle lesen
Weitgehend unbemerkt bleibt allerdings, dass Bildschirm-Rückmeldungen durchaus differenziert zurückgegeben werden, nämlich als "normale" Meldungen auf den Bildschirm alias STDOUT (oder 1) und als Fehlermeldungen auf STDERR (oder 2),
Beispiel gefällig?
>dir *.lo?
Verzeichnis von D:13.01.2005 03:59 4.793 resolve.log
1 Datei(en) 4.793 Bytes
0 Verzeichnis(se), 12.667.240.448 Bytes frei
>dir /b *.lo?
resolve.log
>dir /b *.log >nul
(keine Rückmeldung auf dem Bildschirm)
>dir /b *.lod
Datei nicht gefunden
>dir /b *.lod>nul
Datei nicht gefunden
>dir /b *.lod>nul 2>nul
g) die Prüfung eines ERRORLEVEL ist oft nützlich, sollte man/frau kennen beim Bätche-Bauen.
Kurzgefasst: (fast) jedes Programm/jede CMD-Anweisung gibt einen numerischen ERRORLEVEL-Wert zurück, aus dem sich Erfolg (=0) oder Fehler (1-255) ablesen lassen. Und je nach Erfolg oder Fehler eines Befehls können natürlich unterschiedliche Aktionen in einem Batch folgen.
Beispiel: ">dir /b *.lod>nul 2>nul" liefert ein Errorlevel größer 0, weil, ja ein Fehler aufgetreten ist.
Ein "echo Errorlevel vom letzten Befehl ist: %ERRORLEVEL%" liefert "Errorlevel vom letzten Befehl ist 1"
- A & B .....führe erst A aus, dann B ..also in jedem Fall beide Anweisungen
- A && B Führe erst A aus, nur wenn kein Fehler, dann auch B
B ...führe A aus, nur wenn Fehler auftrete, führe B aus(dir /b *.lod>nul 2>nul) |
i) wenn ich im Batch indirekt andere Anweisungen ausführen lasse, muss ich deren Parameter/Umleitungen unter Umständen im Batch mit ^ "maskieren" (Beispiel folgt weiter unten...beim P.S.)
j) das Allerwichtigste (nicht hauen jetzt): zu jedem CMD-Befehl gibt es Hilfe vom CMD-Prompt aus (ECHO /? oder FOR /? oder SET /? oder einfach HELP for alles)
Zurück zur Praxis.Wir fangen mal mit am CMD-Prompt an, da, wo wir letztes Mal aufgehört haben, bei SET, %variablen%, ECHO. FOR... IN ..DO". Alle Zeilen, die mit einem ">" anfangen, sollen eine Eingabe am CMD-Prompt bedeuten. Ach ja, wer noch den Standardprompt hat, sollte den mal anpassen zum besseren Arbeiten, passt zum Thema Variablen.
Ein bisschen Platz zum Eintippen sollte schon da sein. Wenn der Eingabeprompt schon so ähnlich aussieht wie "D:\Dokumente und Einstellungen\DerBiberAusBremen>" macht es keinen Spaß, etwas einzutippen. Schaffen wir uns Platz ohne Informationsverlust.
:AdvancedStuff
<Ausgangssituation
..gibt gleich eine kleine Aufgabe dazu.
Abfrage der Variablen "prompt"
> set prompt
Die Umgebungsvariable "prompt" ist nicht definiert (die Antwort vom CMD-Interpreter bei Newbies)
prompt=$p$g$ (die Antwort vom CMD-Interpreter bei allen, die schon einen eigenen Prompt definiert haben)
Als Variable ansprechen:
>echo %prompt%
%prompt% (die Antwort bei Newbies) bzw. $p$g (die Antwort bei anderen)
Kleine Workshop-HausAufgabe
Ich möchte gern einen zweizeiligen Prompt haben, dort, wo ich tippe, soll nur ein ">"-Zeichen am Beginn der Zeile stehen. Was bisher im Prompt stand (LW/Pfad etc) soll in die Zeile darüber.
Tipp1: siehe bei ">Prompt /?" .. eine neue Zeile beginnen mit "$_", ein Größer-Zeichen in den Prompt einbauen mit "$g" oder (auf Deutsch) ich möchte, dass die Variable %prompt% mit "$_$g" endet.
Ach ja, aber nur, wenn der %prompt% bisher noch keinen Zeilenumbruch beeinhaltet. Sollte im Prompt schon ein Zeilenunbruch enthalten sein, diesen durch ein Leerzeichen ersetzen.
Tipp2: sollte die Variable %Prompt& noch nicht definert sein, wird sie von Windows als "$p$g" angenommen.
Macht doch mal mit dem gelesenen ( vor allem die Punkte b) und c)) einen ChangePrompt.bat, Editor aufrufen, eintippen, speichern, und starten. Bin gespannt auf die Lösungen.
Für heute soll reichen: Die Variable %prompt% ändern auf zweizeilig geht mit $_
Wer das dauerhaft bei jedem Öffnen eines CMD-Prompts haben möchte, muss eine Benutzervariable Prompt definieren unter Start->Einstellungen, System->Erweitert->Umgebungsvariablen
:GuruStuff
Okay, ich versuch mal ein paar Möglichkeiten auzuzeigen, die beim Rumbätcheln so möglich sind.
Ich wollte ja ein paar Worte zu dem FindLongPath.bat aus dem Teil 1 des kleinen Workshops sagen.
Dazu wäre es sinnvoll, diesen Batch nochmal hier zu posten, aber mit Zeilennummern. Ist einfacher.
Hmm..soll ich sowas zu Fuß machen, Copy & Paste und dann Zeilennummern eingeben? Wer bin ich denn?
Das lass ich mal ein 20-Zeilen-Bätchelchen machen, dieses hier:
::-----snipp NumberMe.bat---
@echo off & SETLOCAL EnableDelayedExpansion
::NumberMe.bat ... eine Textdatei mit ZeilenNummern versehen.
::Version 0.03 Placed into the Public Domain by Biber3@hotmail.de 15.08.2004
::Syntax: %0 InDatei [OutDatei] [/n:Anzahl Stellen der Zeilennummerierung, Default 2]
:: wenn Outdatei nicht angeben wird, dann Ausgabe nur auf Bildschirm/Con:
::----die leidigen Parameter-Prüfungen folgen...*seufz*
IF "%1"=="" (echo Syntaxfehler: %0 InDatei [OutDatei] [/n:Breite Num.]) & (md 2>nul) & goto :eof
IF Not exist "%1" (echo Fehler %0: InDatei "%1" nicht gefunden.) & (md 2>nul) & goto :eof
For %%i in ( con: /n:2 %2 %3) Do call :SetParameter %%i
IF NOT [%pOutput%]==[con:] if exist "%pOutput%" del "%pOutput%"
set /a line=10000
For /F "delims=" %%i in (%1) do (
set /a line=!line!+1
echo !line:~-%pN%! %%i >>%pOutput% )
goto :eof
:SetParameter
set pX=%1
if /i "%pX:~0,3%"=="/n:" (if "%pX:~3%" GTR "0" (set /a pN=%pX:~3%)) ELSE set pOutput=%1
goto :eof
:: -----snapp NumberMe.bat---
01 @echo off & SETLOCAL EnableDelayedExpansion
02 ::NumberMe.bat ... eine Textdatei mit ZeilenNummern versehen.
03 ::Version 0.03 Placed into the Public Domain by Biber3@hotmail.de 15.08.2004
04 ::Syntax: %0 InDatei [OutDatei] [/n:Anzahl Stellen der Zeilennummerierung, Default 2]
05 :: wenn Outdatei nicht angeben wird, dann Ausgabe nur auf Bildschirm/Con:
06 ::----die leidigen Parameter-Prfungen folgen...*seufz*
07 IF "%1"=="" (echo Syntaxfehler: %0 InDatei [OutDatei] [/n:Breite Num.]) & (md 2>nul) & goto :eof
08 IF Not exist "%1" (echo Fehler %0: InDatei "%1" nicht gefunden.) & (md 2>nul) & goto :eof
09 For %%i in ( con: /n:2 %2 %3) Do call :SetParameter %%i
10 IF NOT [%pOutput%]==[con:] if exist "%pOutput%" del "%pOutput%"
11 set /a line=10000
12 For /F "delims=" %%i in (%1) do (
13 set /a line=10013+1
14 echo line:~-%pN% %%i >>%pOutput% )
15 goto :eof
16 :SetParameter
17 set pX=%1
18 if /i "%pX:~0,3%"=="/n:" (if "%pX:~3%" GTR "0" (set /a pN=%pX:~3%)) ELSE set pOutput=%1
19 goto :eof
ad 02: Zwei Befehle in einer Zeile mit & hatte ich schon erwähnt, SETLOCAL EnableDelayedExpansion noch nicht. Siehe dazu bitte die Hilfe bei Setlocal /?
ad 06 Da schwächelt mein Batch...Umlaute gehen verloren. Hätte ich euch auch verschweigen können. Mach ich in der nächsten Version weg. *gg
ad 07 Parameter fehlt? Dann die richtige Syntax anzeigen. Ist guter Stil IMHO.
Fehlermeldung bei Aufruf ">NumberMe" wird expandiert zu: "Syntaxfehler: NumberMe InDatei [OutDatei] [/n:Breite Num.]"
ad 08 Angegebene Datei nicht gefunden. Sollte der Benutzer wissen. Fehlermeldung bei Eingabe ">NumberMe num" wird expandiert zu "Fehler NumberMe: InDatei "num" nicht gefunden."
ad 09 Hier setze ich meine beiden Variablen pOutput und pN erst auf Befault, dann auf das, was der Anwender will.Und zwar mit "call SetParameter %1". Ein "call :xx" wird ausgefüht bis zu einem "goto :eof und kehrt dann zurück. Schaun wir mal, was da passiert.
ad 16 Da springt der "Call" also hin
ad 17 den Parameter, z.b. "con:" oder "/n:2" mal eben zwischenspeichern in Variable pX
ad 18 Prüfen, ob die ersten 3 Stellen="/n" sind, wenn ja und ein numWert folgt, setzen von pN als Zahl bzw.
wenn Nicht die ersten 3 Stellen ="/n" sind und ein numWert folgt, setzen von pOutputmit diesem Parameter
ad 19 Entspricht einem "Return" ..zurück zu Zeile 09
ad 10 Falls die eine Outputdatei angegeben ist und eine alte Version existiert, diese löschen. Aber Bildschirm nich löschen *gg
ad 11 Die Variable "line" brauche ich, um Zeilennummern anzuzeigen. bzw die letzten Stellen pN Stellen davon. Okay, okay, ich gehe in der Praxis davon aus, das nur 2 bis 4 Stellen realistisch sind. Wer damit Texte nit mehr als 9999 Zeilen "nummerieren" will, sollte noch ein paar Nullen dranhängen.
ad 12-14 eine FOR.. IN ..DO -Schleife über mehrere Zeilen. Geht, wenn es geklammert wird.
ad 13 13 ist eine Unglückszahl.14 auch.Hier hat der Aufruf von "NumberMe NumberMe.bat dazu geführt, dass der CMD-Interpreter den Text in der Inputdatei teilweise auflöst,
Eine der lustigen Kuriosiäten des CMD-Interpreters, die man nur bemerkt, wenn man/frau mal Batchdateien mit mehr als 10 Zeilen zu schreiben versucht. Ein Seiteneffekt dieser vom M$ halbherzig implementierten "SETLOCAL EnableDelayedExpansion"-Mimik ist, das alles, was zwischen zwei Anführungszeichen steht, als sofort aufzulösende Variable abgesehen wird. Seiteneffekt im richtigen Leben:
>Type Ausrufezeichen.txt
Microsoft, ihr könnt es !nicht programmieren. lasst mich das machen!am Besten.
Super! Diesen Text versucht der CMD-Interpreter als Variable aufzulösen!
D:\temp>
>NumberMe Ausrufezeichen.txt
01 Microsoft, ihr könnt es am Besten.
02 Super
Variable %line% wird hier auflöst wird zur Zahl 10013...Shit happens. Eigentlich steht hier "set /a line=!line!+1" .Was bedeutet, zähle die %line% um 1 hoch und mach das SOFORT. Grund: der CMD-Interpreter hat ja schon die ganze FOR-Anweisung gelesen und überall schon %line% durch den Wert von %line% ersetzt. Ich will aber den Wert von %line innerhalb der Anweisung verändern.
ad 14 Eigentliche Zeile: "echo !line:~-%pN%! %%i >>%pOutput%". Siehe ad 13). Okay, den meisten von Euch wellen sich die Fussnägel bei so einer Zeile, aber ich kanns erklären..*gg. Was ich hier will (und auch tue) ist, eine Zeile der Form "nn TextblablaBlubb" in eine Datei %pOutput" anzuhängen. Der "TextblablaBlubb" steht in %%i. Und die Zeilennummer bilde ich aus den letzten Stellen der %line%-Variablen, die in dieser Zeile den Wert 10014 hat. Jetzt klar?
%line% ist 10014; %line:~-2% wäre dann der Substring von 10014, die letzten 2 Stellen.
Und die Zahl 2 hole ich aus der Variablen %pN%.
Okay, mal sehen, ob jetzt noch was zum FindLongPath.bat zu sagen bleibt.
Dessen Aufbereitung sieht so aus (Zeile 14 und 50 nachbearbeitet):
01 :: Aufruf FindLongPath [Lw:/Pfad] [Pfadlänge]
02 :: Default Lw:/Pfad=%temp%
03 :: Default Pfadl"nge = 50
04 @ECHO off & SETLOCAL ENABLEEXTENSIONS
05 SET usedvars=tmpdatei reportdatei p1 p1masked p2 x YN PAUSE_D ECHO_D
06 if Defined DebugMyBatches ((set ECHO_D=@ECHO) & (set PAUSE_D=pause) ) else ( set ECHO_D=REM)
07 REM call :Debugshow_vars "Am Start der Batchdatei" ...bei Bedarf das REM entfernen
08 CALL :paramcheck %1 %2
09 :: Nicht einfach weiterlesen... hast Du geguckt, was in :paramcheck passiert???
10 DIR %p1% /aD /b /s >%tmpdatei%
11 IF exist "%reportdatei%" del "%reportdatei%"
12 SET /a p2=%p2%-1
13 SETLOCAL EnableDelayedExpansion
14 FOR /F "delims=" %%i in (%tmpdatei%) do (set "x=%%i") && if "!x:~%p2%,10!" GTR "@" @echo %%i >>%reportdatei%
15 IF EXIST "%reportdatei%" (
16 ECHO Report wurde gespeichert als %reportdatei%.
17 ECHO - Reportdatei vom %date% -- Alle Verzeichnisse >%p2% auf %p1% -->>"%reportdatei%"
18 ECHO - Reportdatei "%reportdatei%" -->>"%reportdatei%"
19 SET /p YN="Auf %p1% wurden Pfade mit L"nge gr"áer %p2% gefunden. Anzeigen (J/N?) "
20 IF /i ""=="J" TYPE "%reportdatei%" |MORE
21 ) ELSE (
22 ECHO Keine Pfade l"nger als %p2% Zeichen im Pfad %p1% gefunden.
23 )
24 ENDLOCAL
25 CALL :DebugShow_vars
26 CALL :cleanup
27 GOTO :eof
28 -------------------
29 :::::::::::: ParamCheck ... Hier werden die Parameter %1 und %2 geprft daraus %p1% und %p2% abgeleitet.
30 :: Param 1 : Laufwerksbuchstabe oder Verzeichnis; Default %temp%
31 :::::::::::: Dieser Parameter wird als Substring in den Variablen %tmpdatei% und %reportdatei% verwendet
32 :::::::::::: Dafr werden ":" und "\" durch "$" und"_" ersetzt, um einen gltigen Dateinamen zu bilden.
33 :::::::::::: dazu Zwischenspeicherung in Variable %p1% und %p1masked%
34 :::::::::::: Syntax dazu siehe SET /? und dort.. %PATH:str1=str2%
35 :: Param 2:: zu prfende L"nge der Verzeichnisse ... Default 50
36 :ParamCheck
37 IF (%1)==() (SET p1=%temp%) ELSE (SET p1=%1)
38 IF (%2)==() (SET /a p2=50 ) ELSE (SET /a p2=%2)
39 SET p1masked=%p1::=$%
40 SET p1masked=%p1masked:\=_%
41 %ECHO_D% p1->p1masked ist %p1%->%p1masked%; p2 ist %p2%
42 SET "tmpdatei=%temp%\%computername%_%p1masked%_All.lst"
43 SET "Reportdatei=d:\temp\%computername%_%p1masked%_%p2%.lst"
44 CALL :Debugshow_vars "Nach Var-Setzen"
45 goto :eof
46 --------------------
47 :DebugShow_vars
48 IF DEFINED DebugMyBatches (
49 SETLOCAL ENABLEDELAYEDEXPANSION
50 FOR %%i IN (%usedvars%) DO (ECHO [%~1] Variable %%i="!%%i!" )
51 ENDLOCAL
52 PAUSE
53 )
54 GOTO :eof
55 -----------------
56 :cleanup
57 %ECHO_D% in Subroutine :Cleanup
58 IF EXIST "%tmpdatei%" del "%tmpdatei%" & %ECHO_D% Datei %tmpdatei% wird gelöscht.
59 FOR %%i IN (%usedvars% usedvars) DO @IF DEFINED %%i (
60 (IF DEFINED DebugMyBatches echo %%i wird freigegeben) & (SET %%i=))
60a REM **s.u. (IF DEFINED ECHO_D %ECHO_D% %%i wurde freigegeben) & (SET %%i=))
61 GOTO :eof
62 ::---------End of FindLongPath.bat -------
Konsequenz: Umlaute sparsam verwenden in Batches - auch im Jahr 2005 und bei 64-Bit-Architekturen!
ad 04 @echo off & SETLOCAL ENABLEEXTENSIONS ... EnableExtensions ist Standard bei W2k-XP. Hätte ich mir schenken können, Dann wäre es kürzer geworden.
ad 05 Brauche ich für nur meine Pseudo-Debug-Mimik. Wäre sonst auch überflüssig.
ad 06 Eine meine Standardzeilen in Batches (per Copy & Paste). Damit kann ich Batches Zeilen einbauen, die im Normalbetrieb als Kommentar interpretiert werden, Wenn ich eine Variable "DebugMyBatches" vor dem Start der Batchdatei gesetzt habe, werden aus den "REM "-Kommentarzeilen Echo und Pause.Anweisungen.
Ach ja, geschwindelt war letztes Mal, dass ihr "Set DebugMyBatches=42" eingeben müsst. "Set DebugMyBatches=41" hätte auch gereicht.
ad 08 springt zu :ParamCheck in Zeile 36...ich jetzt auch
ad 37-38 Defaults bzw userdefininierte Parameter setzen
ad 39-40 Setze Wert von %p1masked% auf p1 (Laufwerk/Pfad), ersetze alle ":" und "\" durch "$" und "_"
ad 41 im Normalbetrieb Kommentarzeile, Im Debugmodus (%DebugMyBatches% gesetzt) eine Echo-Zeile
ad 42-43 Nix besonderes, außer.. dass sich statt SET VAR=wert auch SET "VAR=wert" schreiben lässt. Braucht man manchmal.
ad 44 Na klar, wer mitgelesen hat...ich hätte auch als Zeile 06a schreiben können :
if Defined DebugMyBatches (set "CALL_SHOW_VARS_D=call :Debugshow_vars") else set CALL_SHOW_VARS_D=REM
und Zeile 44 ändern auf %CALL_SHOW_VARS_D% "Nach Var-Setzen" ...da wäre der Batch im Normalbetrieb schneller. *gg ....aber im DebugMode Sprung zu 47-54
ad 52 Da hatte ich zuerst ein %PAUSE_D% stehen...aber ist ja Unsinn. Da kommt er nur im Debugmodus hin.
Bugfix 58 und 60 siehe unten, Posting und Fix von JohnnyB
ad 45 und Return To Caller...zurück zu Zeile 08...ganz ans Ende davon..
ad 10 Alle Verzeichnisse z'amsammeln in einer Textdatei..
ad 12 SET /a p2=%p2%-1 ..an ja, nicht ganz sauber.. Richtig wäre gewesen: SET /a p3=%p2%-1, aber ich wollte keine zusätzliche Variable p3 definieren und habe %p2% um eins gemindert, weil ich das später als Substring-Parameter brauche. Geschlampt. Aber is ja auch nur 'n Batch. *trotzdem schäm*
ad 13 SETLOCAL EnableDelayedExpansion... kennt ihr ja jetzt
ad 14 FOR /F "delims=" %%i in (%tmpdatei%) do ....mit allen Zeilen der %tmpdatei%
(set "x=%%i") && ...... jede Zeile in Variable x speichern und dann...
if "!x:~%p2%,10!" GTR "@" ... und alle Zeilen mit Substring(p2, 10) größer ist als "@"
@echo %%i >>%reportdatei% ... in die Reportdatei anhängen.
ad 15-23 Nix Aufregendes
ad 24 ENDLOCAL ist die Klammerzu zu Zeile 13.
ad 25 siehe ad 44
ad 26 alte Gewohnheiten..nach dem Variablen definieren auch wieder alle löschen.
27 GOTO :eof ...Hier nun wirklich ein Return. Gehe zum Ende der Welt. Bzw. des Batches.
So, ein bisschen was hebe ich mir noch für den nächsten Teil des Workshops auf.
Für heute noch eine kleine Kuriosität zun FOR...IN..DO -Befehl.
Laut Dokumentation sind als Zählvariablen erlaubt %a...bis %z und %A..bis %Z.
Also müsste doch folgende Anweisung einen Syntaxfehler melden:
>FOR %@ IN (Microsofts Praktikanten können super programmieren) do @echo %@
Frank / der Biber aus Bremen
P.S. Für alle, die nur mitgelesen haben wegen der versprochenen GetIP.Bat's ...nächstes Mal.
Na gut, einen letzten Oneliner noch ...
::-------snipp--GetIPviaPing.bat (dt. Bei US-Version "Reply" statt "Antwort" ---
for /F "Tokens=3 Delims=: " %%i in ('@ping -n 1 "%computername%"^|Find "Antwort"') do ( set IP=%%i )
:: ------snapp--GetIPviaPing.bat ---
Weiter geht es hier:
Workshop Batch for Runaways - Part III - Datums- und Zeitvariablen im Batch
...und immer passend zum Workshop:
Tutorial zur FOR-Schleife von Friemler
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 14413
Url: https://administrator.de/contentid/14413
Ausgedruckt am: 21.11.2024 um 18:11 Uhr
20 Kommentare
Neuester Kommentar
<font color=red>:GuruStuff</font>
Okay, ich versuch mal ein paar
Möglichkeiten auzuzeigen, die beim
Rumbätcheln so möglich sind.
Ich wollte ja ein paar Worte zu dem
FindLongPath.bat aus dem Teil 1 des kleinen
Workshops sagen.
Dazu wäre es sinnvoll, diesen Batch
nochmal hier zu posten, aber mit
Zeilennummern. Ist einfacher.
Hmm..soll ich sowas zu Fuß machen,
Copy & Paste und dann Zeilennummern
eingeben? Wer bin ich denn?
Das lass ich mal ein
20-Zeilen-Bätchelchen machen, ...
Okay, ich versuch mal ein paar
Möglichkeiten auzuzeigen, die beim
Rumbätcheln so möglich sind.
Ich wollte ja ein paar Worte zu dem
FindLongPath.bat aus dem Teil 1 des kleinen
Workshops sagen.
Dazu wäre es sinnvoll, diesen Batch
nochmal hier zu posten, aber mit
Zeilennummern. Ist einfacher.
Hmm..soll ich sowas zu Fuß machen,
Copy & Paste und dann Zeilennummern
eingeben? Wer bin ich denn?
Das lass ich mal ein
20-Zeilen-Bätchelchen machen, ...
...Ähm oder ich tippe:
echo |findstr /n .* quelldatei.bat > zieldatei.txt
in meine CMD und bekomme gleiches Ergebnis.
Nix für ungut ;)
LG
Rantanplan
Hallo Biber,
erst einmal ein großes Lob und Danke für deine tollen Tuts und Anregungen und mach'
bitte weiter.
Eine Anmerkung hätte ich dann aber doch noch...
Aus eigener Erfahrung weiss ich, dass es mitunter schwer ist den eigenen Text, die eigenen
Doks oder Sourcen zu lesen, zu korrigieren und zu setzen, daher ein kleiner Hinweis:
In Abschnit h) ist glaube ich ein c'n'p error hineingekommen
(dir /b *.lod>nul 2>nul) && (echo Fehler bei beim Dir-Befehl, Errorlevel ist %ERRORLEVEL% & goto :end)
müßte dies nicht eher so heißen:
Dann taucht noch der folgenden String unterhalb des Textblocks zur Ausrufezeichen.txt auf:
</font size=-2>
Noch einmal, eine tolle Arbeit, es zeigt mir außerdem die 'DOS'-Batches sind nicht tot und
meine 'kruden' Automatisierungs-Ideen lassen sich auch damit noch lösen
mfg
Axel
erst einmal ein großes Lob und Danke für deine tollen Tuts und Anregungen und mach'
bitte weiter.
Eine Anmerkung hätte ich dann aber doch noch...
Aus eigener Erfahrung weiss ich, dass es mitunter schwer ist den eigenen Text, die eigenen
Doks oder Sourcen zu lesen, zu korrigieren und zu setzen, daher ein kleiner Hinweis:
In Abschnit h) ist glaube ich ein c'n'p error hineingekommen
müßte dies nicht eher so heißen:
Dann taucht noch der folgenden String unterhalb des Textblocks zur Ausrufezeichen.txt auf:
</font size=-2>
Noch einmal, eine tolle Arbeit, es zeigt mir außerdem die 'DOS'-Batches sind nicht tot und
meine 'kruden' Automatisierungs-Ideen lassen sich auch damit noch lösen
mfg
Axel
Schönes Tutorial, Biber!
> set /a bewertung=5
Ich habe das alles mal nicht per cnp, sonder per 10-Fingers ausprobiert und dabei einen Fehler entdeckt, der hier zwar nicht viel ausmacht, aber in anderen Situationen u.U. graue Haare verursacht. Hier führt er dazu, daß die :cleanup Routine nicht funktioniert:
In Zeile 06 setzt Du für den Fall, daß die Umgebungsvariable DebugMyBatches nicht gesetzt ist, die Variable ECHO_D auf REM. Das Problem dabei ist, das alles was dann nach dem REM in einer Zeile steht ignoriert wird und noch schlimmer, ein REM in einer FOR ... IN ... DO -Schleife zum Abbruch dieser Schliefe führt. Zumindest tut es das in den Zeilen 59/60.
Das Fatale an der Sache ist, daß während des Debuggings alles ganz normal läuft, und wenn man sich dann entschließt, die Debugging-Anzeige auszuschalten, sprich die DebugMyBatches wieder zu löschen, fängt der Mist an. In diesem konkreten Beispiel heißt das, das tmpfile wird nicht gelöscht und die Variablen bleiben auch nach Beendigung des Batch im Speicher.
Folgende Änderung der Zeilen 58 und 60 schaffen da Abhilfe:
In Zeile 58 wird also zuerst die tmpdatei gelöscht und ggf. anschließend ausgegeben, wenn hier dann ein REM steht ist es egal. In Zeile 60 wird nicht ECHO_D abgefragt, denn das ist ja auf jeden Fall definiert, entweder als ECHO oder eben als REM und das REM können wir hier absolut nicht gebrauchen. Wenn also DebugMyBatches definiert ist, dann wird ausgegeben, welche Variable wieder freigegeben wird, ansonsten ist Ruhe.
Wie gesagt, in diesem Fall war der Fehler nicht so schlimm, wenn jedoch so ein REM in einem Anweisungsblock mit kritischen Anweisungen steht, können schon mal komische Sachen passieren. Und den Fehler dann zu finden kann richtig blöd werden, weil wenn man das Debugging dann aktiviert tritt der Fehler nicht mehr auf. So etwas kann einen den letzten Nerv kosten.
Schönen Gruß,
Johnny.
> set /a bewertung=5
Ich habe das alles mal nicht per cnp, sonder per 10-Fingers ausprobiert und dabei einen Fehler entdeckt, der hier zwar nicht viel ausmacht, aber in anderen Situationen u.U. graue Haare verursacht. Hier führt er dazu, daß die :cleanup Routine nicht funktioniert:
In Zeile 06 setzt Du für den Fall, daß die Umgebungsvariable DebugMyBatches nicht gesetzt ist, die Variable ECHO_D auf REM. Das Problem dabei ist, das alles was dann nach dem REM in einer Zeile steht ignoriert wird und noch schlimmer, ein REM in einer FOR ... IN ... DO -Schleife zum Abbruch dieser Schliefe führt. Zumindest tut es das in den Zeilen 59/60.
Das Fatale an der Sache ist, daß während des Debuggings alles ganz normal läuft, und wenn man sich dann entschließt, die Debugging-Anzeige auszuschalten, sprich die DebugMyBatches wieder zu löschen, fängt der Mist an. In diesem konkreten Beispiel heißt das, das tmpfile wird nicht gelöscht und die Variablen bleiben auch nach Beendigung des Batch im Speicher.
Folgende Änderung der Zeilen 58 und 60 schaffen da Abhilfe:
58 IF EXIST "%tmpdatei%" (del "%tmpdatei%") & %ECHO_D% Datei %tmpdatei% wird gelöscht.
...
60 (IF DEFINED DebugMyBatches echo %%i wird freigegeben) & (SET %%i=))
In Zeile 58 wird also zuerst die tmpdatei gelöscht und ggf. anschließend ausgegeben, wenn hier dann ein REM steht ist es egal. In Zeile 60 wird nicht ECHO_D abgefragt, denn das ist ja auf jeden Fall definiert, entweder als ECHO oder eben als REM und das REM können wir hier absolut nicht gebrauchen. Wenn also DebugMyBatches definiert ist, dann wird ausgegeben, welche Variable wieder freigegeben wird, ansonsten ist Ruhe.
Wie gesagt, in diesem Fall war der Fehler nicht so schlimm, wenn jedoch so ein REM in einem Anweisungsblock mit kritischen Anweisungen steht, können schon mal komische Sachen passieren. Und den Fehler dann zu finden kann richtig blöd werden, weil wenn man das Debugging dann aktiviert tritt der Fehler nicht mehr auf. So etwas kann einen den letzten Nerv kosten.
Schönen Gruß,
Johnny.
Sehr netter Workshop, vielen Dank.
Das einzige was ich nicht verstehe ist: @Biber, WTF? Wieso verzichtest du auf BLUTJUNGE, ROTHAARIGE Praktikantinnen ??? ;)
Gruß, Daniel
Das einzige was ich nicht verstehe ist: @Biber, WTF? Wieso verzichtest du auf BLUTJUNGE, ROTHAARIGE Praktikantinnen ??? ;)
Gruß, Daniel
@Biber
Ich habe gerade mal ein bißchen mit der o.g. Batchdatei herumgebastelt, da ich ein Tool gesucht habe, das mir zu
lange Dateinamen, die durch Verschieben von Ordnern entstanden sind, herausfindet.
Beim Übertragen der Dateien von dem Ordner 'C:\Eigene Dateien\...' von meinem alten Win98-Rechner in das neue
XP-Verzeichnis 'C:\Dokumente und Einstellungen\Benutzername\Eigene Dateien\...' ist der Pfad nicht unerheblich
(fast 30 Zeichen) länger geworden
Leider ist mir hier bei dem vorliegenden Batch-File aufgefallen, daß manches nicht so funktioniert wie angedacht:
Zuerst mußte ich in der Zeile
10 DIR %p1% /aD /b /s >%tmpdatei%
die Option /aD entfernen, denn sonst werden nur Verzeichnissnamen, nicht aber die Dateinamen auf die Länge
überprüft.
Weiterhin besteht das Problem, daß offensichtlich in Zeile 15-24 die mit set /p zugewiesene Variable YN bei der
Schlußabfrage für das Anzeigen des Inhaltes der erstellten Report-Datei nicht benutzt werden kann. Erst wenn
die Zugriffe auf die Variable außerhalb der Klammer der If exist-Abfrage erfolgen, funktioniert die Abfrage. Innerhalb
der Klammer komischerweise nicht?!?
Woran kann das liegen?
Hmmmm... - auf jeden Fall habe ich lange herumprobiert, um dann kurzerhand - vielleicht geht es eleganter - eine
funktionierende Schlußabfrage zu erstellen:
IF NOT EXIST "%reportdatei%" ECHO Keine Pfade laenger als %p2% Zeichen im Pfad %p1% gefunden. & goto :Ende
ECHO Report wurde gespeichert als %reportdatei%.
ECHO - Reportdatei vom %date% -- Alle Verzeichnisse >%p2% auf %p1% -->>"%reportdatei%"
ECHO - Reportdatei "%reportdatei%" -->>"%reportdatei%"
SET /p YN="Auf %p1% wurden Pfade mit Laenge groesser %p2% gefunden. Anzeigen [J/N?]"
if "%YN%"=="j" TYPE "%reportdatei%" |MORE
:Ende
ENDLOCAL
Und noch etwas ist mir aufgefallen: Es gibt Probleme mit dem Angeben des Pfades, auf den die Datei angewendet
werden soll:
Wenn es z.B. um C:\Dokumente und Einstellungen geht, wird nicht der gesamte Name als Verzeichnis erkannt.
Gebe ich den Pfad dann in "" ein ("C:\Dokumente und Einstellungen"), dann gibt es Probleme mit der zu erstellenden
Datei, da das Batchfile versucht, den Pfad mitsamt den Anführungszeichen in den Dateinamen einzubauen.
Allerdings habe ich noch keine Idee, wie man dies umgehen kann. Wahrscheinlich müsste man eine zusätzliche
Hilfsvariable schaffen, in der der Pfad ohne die Anführungszeichen abgelegt wird.
Aber vielleicht habt Ihr als Profis hier im Forum ja die passenden Vorschläge
André
Ich habe gerade mal ein bißchen mit der o.g. Batchdatei herumgebastelt, da ich ein Tool gesucht habe, das mir zu
lange Dateinamen, die durch Verschieben von Ordnern entstanden sind, herausfindet.
Beim Übertragen der Dateien von dem Ordner 'C:\Eigene Dateien\...' von meinem alten Win98-Rechner in das neue
XP-Verzeichnis 'C:\Dokumente und Einstellungen\Benutzername\Eigene Dateien\...' ist der Pfad nicht unerheblich
(fast 30 Zeichen) länger geworden
Leider ist mir hier bei dem vorliegenden Batch-File aufgefallen, daß manches nicht so funktioniert wie angedacht:
Zuerst mußte ich in der Zeile
10 DIR %p1% /aD /b /s >%tmpdatei%
die Option /aD entfernen, denn sonst werden nur Verzeichnissnamen, nicht aber die Dateinamen auf die Länge
überprüft.
Weiterhin besteht das Problem, daß offensichtlich in Zeile 15-24 die mit set /p zugewiesene Variable YN bei der
Schlußabfrage für das Anzeigen des Inhaltes der erstellten Report-Datei nicht benutzt werden kann. Erst wenn
die Zugriffe auf die Variable außerhalb der Klammer der If exist-Abfrage erfolgen, funktioniert die Abfrage. Innerhalb
der Klammer komischerweise nicht?!?
Woran kann das liegen?
Hmmmm... - auf jeden Fall habe ich lange herumprobiert, um dann kurzerhand - vielleicht geht es eleganter - eine
funktionierende Schlußabfrage zu erstellen:
IF NOT EXIST "%reportdatei%" ECHO Keine Pfade laenger als %p2% Zeichen im Pfad %p1% gefunden. & goto :Ende
ECHO Report wurde gespeichert als %reportdatei%.
ECHO - Reportdatei vom %date% -- Alle Verzeichnisse >%p2% auf %p1% -->>"%reportdatei%"
ECHO - Reportdatei "%reportdatei%" -->>"%reportdatei%"
SET /p YN="Auf %p1% wurden Pfade mit Laenge groesser %p2% gefunden. Anzeigen [J/N?]"
if "%YN%"=="j" TYPE "%reportdatei%" |MORE
:Ende
ENDLOCAL
Und noch etwas ist mir aufgefallen: Es gibt Probleme mit dem Angeben des Pfades, auf den die Datei angewendet
werden soll:
Wenn es z.B. um C:\Dokumente und Einstellungen geht, wird nicht der gesamte Name als Verzeichnis erkannt.
Gebe ich den Pfad dann in "" ein ("C:\Dokumente und Einstellungen"), dann gibt es Probleme mit der zu erstellenden
Datei, da das Batchfile versucht, den Pfad mitsamt den Anführungszeichen in den Dateinamen einzubauen.
Allerdings habe ich noch keine Idee, wie man dies umgehen kann. Wahrscheinlich müsste man eine zusätzliche
Hilfsvariable schaffen, in der der Pfad ohne die Anführungszeichen abgelegt wird.
Aber vielleicht habt Ihr als Profis hier im Forum ja die passenden Vorschläge
André
Hallo doc_jochim!
Mit ein paar eingestreuten Anführungszeichen (und anderem Kroppzeug ) sollte es auch mit "C:\Dokumente und Einstellungen" klappen ...
Da die Ausgabe mit "type" (vor allem bei kleineren Werten für die zu prüfende Länge) etwas mühsam werden kann, habe ich ersatzweise einen "notepad"-Aufruf eingebaut.
Noch ein Hinweis zur %reportdatei%: Das Verzeichnis, in welchem diese erstellt werden soll (siehe Zeile 43) muss bereits existieren ...
Grüße
bastla
@Biber - Entschuldige bitte, dass ich Deine Abwesenheit ausnutze, mich an Deinem Batch zu vergreifen ...
Mit ein paar eingestreuten Anführungszeichen (und anderem Kroppzeug ) sollte es auch mit "C:\Dokumente und Einstellungen" klappen ...
Da die Ausgabe mit "type" (vor allem bei kleineren Werten für die zu prüfende Länge) etwas mühsam werden kann, habe ich ersatzweise einen "notepad"-Aufruf eingebaut.
Noch ein Hinweis zur %reportdatei%: Das Verzeichnis, in welchem diese erstellt werden soll (siehe Zeile 43) muss bereits existieren ...
:: Aufruf FindLongPath [Lw:/Pfad] [Pfadlänge]
:: Default Lw:/Pfad=%temp%
:: Default Pfadl"nge = 50
@ECHO off & SETLOCAL ENABLEEXTENSIONS
SET usedvars=tmpdatei reportdatei p1 p1masked p2 x YN PAUSE_D ECHO_D
if Defined DebugMyBatches ((set ECHO_D=@ECHO) & (set PAUSE_D=pause) ) else ( set ECHO_D=REM)
REM call :Debugshow_vars "Am Start der Batchdatei" ...bei Bedarf das REM entfernen
CALL :paramcheck %1 %2
:: Nicht einfach weiterlesen... hast Du geguckt, was in :paramcheck passiert???
DIR "%p1%" /s /b >"%tmpdatei%"
IF exist "%reportdatei%" del "%reportdatei%"
SET /a p2=%p2%-1
SETLOCAL EnableDelayedExpansion
FOR /F "usebackq delims=" %%i in ("%tmpdatei%") do (set "x=%%i") && if "!x:~%p2%,10!" GTR "@" @echo %%i >>"%reportdatei%"
IF EXIST "%reportdatei%" (
ECHO Report wurde gespeichert als %reportdatei%.
ECHO - Reportdatei vom %date% -- Alle Verzeichnisse ^>%p2% auf %p1% --^>^>"%reportdatei%"
ECHO - Reportdatei "%reportdatei%" --^>^>"%reportdatei%"
SET /p YN="Auf %p1% wurden Pfade mit L„nge gr”áer %p2% gefunden. Anzeigen (J/N?) "
IF /i "!YN!"=="J" notepad "%reportdatei%"
) ELSE (
ECHO Keine Pfade l"nger als %p2% Zeichen im Pfad %p1% gefunden.
)
ENDLOCAL
CALL :DebugShow_vars
CALL :cleanup
GOTO :eof
-------------------
:::::::::::: ParamCheck ... Hier werden die Parameter %1 und %2 geprft daraus %p1% und %p2% abgeleitet.
:: Param 1 : Laufwerksbuchstabe oder Verzeichnis; Default %temp%
:::::::::::: Dieser Parameter wird als Substring in den Variablen %tmpdatei% und %reportdatei% verwendet
:::::::::::: Dafr werden ":" und "\" durch "$" und"_" ersetzt, um einen gltigen Dateinamen zu bilden.
:::::::::::: dazu Zwischenspeicherung in Variable %p1% und %p1masked%
:::::::::::: Syntax dazu siehe SET /? und dort.. %PATH:str1=str2%
:: Param 2:: zu prfende L„nge der Verzeichnisse ... Default 50
:ParamCheck
IF (%1)==() (SET "p1=%temp%") ELSE (SET "p1=%~1")
IF (%2)==() (SET /a p2=50 ) ELSE (SET /a p2=%2)
SET "p1masked=%p1::=$%"
SET "p1masked=%p1masked:\=_%"
%ECHO_D% p1-^>p1masked ist %p1%-^>%p1masked%; p2 ist %p2%
SET "tmpdatei=%temp%\%computername%_%p1masked%_All.lst"
SET "Reportdatei=D:\Temp\%computername%_%p1masked%_%p2%.lst"
CALL :Debugshow_vars "Nach Var-Setzen"
goto :eof
--------------------
:DebugShow_vars
IF DEFINED DebugMyBatches (
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%i IN (%usedvars%) DO (ECHO [%~1] Variable %%i="!%%i!" )
ENDLOCAL
PAUSE
)
GOTO :eof
-----------------
:cleanup
%ECHO_D% in Subroutine :Cleanup
IF EXIST "%tmpdatei%" del "%tmpdatei%" & %ECHO_D% Datei %tmpdatei% wird gel”scht.
FOR %%i IN (%usedvars% usedvars) DO @IF DEFINED %%i (
(IF DEFINED DebugMyBatches echo %%i wird freigegeben) & (SET %%i=))
REM **s.u. (IF DEFINED ECHO_D %ECHO_D% %%i wurde freigegeben) & (SET %%i=))
GOTO :eof
::---------End of FindLongPath.bat -------
bastla
@Biber - Entschuldige bitte, dass ich Deine Abwesenheit ausnutze, mich an Deinem Batch zu vergreifen ...
Hallo bastla,
Wie wäre es denn dann noch mit einer Sicherheitsabfrage, damit es nicht nach stundenlangem Durchsuchen
tief verschachtelter Verzeichnisbäume einen Fehler beim Schreiben der Report-Datei gibt.
Etwa in der Art:
FOR /f "delims=" %%i IN ('ECHO %Reportdatei%') DO (
IF NOT EXIST "%%~di" (ECHO Das für die Ergebnisdatei angegebene LW %%~di existiert nicht & goto :eof)
IF NOT EXIST "%%~dpi" (MD "%%~dpi"))
als Zeilen 8a, 8b und 8c.
So habe ich mir zumindest meine Sicherheitsabfrage gestrickt, bei dem Versuch, das Problem zu lösen.
Warum eigentlich @echo, wenn oben sowieso schon @echo off steht?
Irgendwie ist das ein bißchen doppelt gemoppelt. Hier steht gegenüber Zeile 17 doch keine zusätzliche Information - oder?
Warum eigentlich nicht der gute, alte Choice-Befehl? Dann könnte man sich das Drücken der Enter-Taste sparen
Ich bin mir leider bzgl. des korrekten Syntax einiger Befehle im Moment noch nicht ganz so sicher, da ich mich im
Rahmen der Notwendigkeit zur Übertragung eines durch Verschieben und Umbenennen von Ordnern fehlerhaft
gewordenen Verzeichnisbaums mit zu langen 'Ästen' erst seit einigen Tagen mit den Batch-Befehlen beschäftigt habe.
Zur Info habe ich meine Version als gezippte 'files.bat' mal zum Download unter
http://www.urlaub-in-sorgenlos.de/fehler/pfadbatch.zip zum Anschauen hinterlegt.
Ich habe leider ein bißchen an den REMs und damit an der Dokumentation gespart. Aber bei Fragen einfach fragen
Ein Posten des kompletten Codes würde hier sicherlich nicht dazu führen, daß der Thread übersichtlicher wird...
André
Noch ein Hinweis zur %reportdatei%: Das Verzeichnis, in welchem diese erstellt werden soll (siehe Zeile 43)
muss bereits existieren ...
muss bereits existieren ...
Wie wäre es denn dann noch mit einer Sicherheitsabfrage, damit es nicht nach stundenlangem Durchsuchen
tief verschachtelter Verzeichnisbäume einen Fehler beim Schreiben der Report-Datei gibt.
Etwa in der Art:
FOR /f "delims=" %%i IN ('ECHO %Reportdatei%') DO (
IF NOT EXIST "%%~di" (ECHO Das für die Ergebnisdatei angegebene LW %%~di existiert nicht & goto :eof)
IF NOT EXIST "%%~dpi" (MD "%%~dpi"))
als Zeilen 8a, 8b und 8c.
So habe ich mir zumindest meine Sicherheitsabfrage gestrickt, bei dem Versuch, das Problem zu lösen.
FOR /F "usebackq delims=" %%i in ("%tmpdatei%") do (set "x=%%i") && if "!x:~
%p2%,10!" GTR "@" @echo %%i >>"%reportdatei%"
%p2%,10!" GTR "@" @echo %%i >>"%reportdatei%"
Warum eigentlich @echo, wenn oben sowieso schon @echo off steht?
ECHO - Reportdatei "%reportdatei%" --^>^>"%reportdatei%" (Zeile 18)
Irgendwie ist das ein bißchen doppelt gemoppelt. Hier steht gegenüber Zeile 17 doch keine zusätzliche Information - oder?
SET /p YN="Auf %p1% wurden Pfade mit L„nge gr”áer %p2% gefunden. Anzeigen (J/N?) "
Warum eigentlich nicht der gute, alte Choice-Befehl? Dann könnte man sich das Drücken der Enter-Taste sparen
Ich bin mir leider bzgl. des korrekten Syntax einiger Befehle im Moment noch nicht ganz so sicher, da ich mich im
Rahmen der Notwendigkeit zur Übertragung eines durch Verschieben und Umbenennen von Ordnern fehlerhaft
gewordenen Verzeichnisbaums mit zu langen 'Ästen' erst seit einigen Tagen mit den Batch-Befehlen beschäftigt habe.
Zur Info habe ich meine Version als gezippte 'files.bat' mal zum Download unter
http://www.urlaub-in-sorgenlos.de/fehler/pfadbatch.zip zum Anschauen hinterlegt.
Ich habe leider ein bißchen an den REMs und damit an der Dokumentation gespart. Aber bei Fragen einfach fragen
Ein Posten des kompletten Codes würde hier sicherlich nicht dazu führen, daß der Thread übersichtlicher wird...
André
@Biber
Hmmm... - da habe ich wohl was nicht mitbekommen. Ich fand die Abfrage bisher immer ganz praktisch, wenn nur ein Zeichen gefordert war. Dann konnte man sich das Drücken der Return-Taste sparen.
Was ist denn so schlimm an dem choice-Befehl?
Bummbummm...bummbummm...bummbummm... Es lebt und die Ideen haben mir sehr weitergeholfen.
Gibt es eigentlich eine Möglichkeit, die in Dateinamen hineingerutschten Ähs, Öhs, Ühs, Esszetts... in der Report-Datei so darzustellen, daß man sie nicht unbedingt mit den edit-Befehl anschauen muß, sondern daß ein Öffnen im Notepad oder in Word möglich ist, ohne daß die Zeichen durch komische Symbole ersetzt werden?
André
Choice.com und ForFiles.exe waren/sind aus meiner Sicht die in den letzten Jahren herausragendsten Verirrungen,
die durch die Redmonder Qualitätskontrolle geschlüpft sind.
die durch die Redmonder Qualitätskontrolle geschlüpft sind.
Hmmm... - da habe ich wohl was nicht mitbekommen. Ich fand die Abfrage bisher immer ganz praktisch, wenn nur ein Zeichen gefordert war. Dann konnte man sich das Drücken der Return-Taste sparen.
Was ist denn so schlimm an dem choice-Befehl?
Meine Absicht war [...] viel bescheidener: Wenn diese Skizzen dazu geführt haben, dass der eine oder andere Ansatz tatsächlich in real vor sich hinschnurrenden Gebrauchsbätchen irgendwo "in der richtigen Welt" weiterlebt... dann hat diese Anleitung ihren Sinn erfüllt.
Bummbummm...bummbummm...bummbummm... Es lebt und die Ideen haben mir sehr weitergeholfen.
Gibt es eigentlich eine Möglichkeit, die in Dateinamen hineingerutschten Ähs, Öhs, Ühs, Esszetts... in der Report-Datei so darzustellen, daß man sie nicht unbedingt mit den edit-Befehl anschauen muß, sondern daß ein Öffnen im Notepad oder in Word möglich ist, ohne daß die Zeichen durch komische Symbole ersetzt werden?
André
Hallo doc_jochim!
Um Dir hoffentlich das Suchen (bzw einen neuen Beitrag) zu ersparen: Pfadangaben mit Umlauten
Grüße
bastla
Um Dir hoffentlich das Suchen (bzw einen neuen Beitrag) zu ersparen: Pfadangaben mit Umlauten
Grüße
bastla
@Biber
Erst mal ein fettes Lob an Dich für diesen Super Workshop...Alle Daumen gehen hoooch
Allerdings hätte ich da doch noch ein Punkt der leider unbeantwortet bleibt.
Ich hätte gerne die Prozessor Architektur bzw. Betriebssystem Variante in einer Zeile abgefragt...meine Idee war folgende:
if "%PROCESSOR_ARCHITECTURE%" == "x86" (set progdir=%ProgramFiles%) ELSE (set progdir=%ProgramFiles(x86)%)
das führt aber zu einem Syntax Fehler, da in der x86 Systemvariable bereits eine Klammer enthalten ist!
Ich habe bereits versucht diese mit einem ^ zu maskieren...ohne erfolg! -> Gibt es hier evtl. ein anderes Zeichen das man nutzen kann ...oder man benutzt für die unterteilung der zwei set commandos etwas anderes statt den normalen Klammern!?
als workaround habe ich es z.zt. so gelöst (gefällt mir persönlich eher weniger)
if "%PROCESSOR_ARCHITECTURE%" == "x86" goto x86
set progdir=%ProgramFiles(x86)%
goto copyjob
:x86
set progdir=%ProgramFiles%
:copyjob
Vielleicht habt ihr ja noch eine Idee!?
Gruß
Dirk
Nachtrag:
folgende Zeile hat dann jetzt doch funktioniert...aber das Ergebnis ist irgendwie nicht wie erwünscht
if "%PROCESSOR_ARCHITECTURE%" == "x86" (set progdir=%ProgramFiles%) ELSE (set progdir=%ProgramFiles^(x86^)%)
der Output ist dann aber keine Variable sondern Text!
C:\>echo %progdir%
%ProgramFiles(x86)%
ich dachte das hätte ich schon mal Probiert und es hatte garnicht funktioniert...aber egal!
Erst mal ein fettes Lob an Dich für diesen Super Workshop...Alle Daumen gehen hoooch
Allerdings hätte ich da doch noch ein Punkt der leider unbeantwortet bleibt.
Ich hätte gerne die Prozessor Architektur bzw. Betriebssystem Variante in einer Zeile abgefragt...meine Idee war folgende:
if "%PROCESSOR_ARCHITECTURE%" == "x86" (set progdir=%ProgramFiles%) ELSE (set progdir=%ProgramFiles(x86)%)
das führt aber zu einem Syntax Fehler, da in der x86 Systemvariable bereits eine Klammer enthalten ist!
Ich habe bereits versucht diese mit einem ^ zu maskieren...ohne erfolg! -> Gibt es hier evtl. ein anderes Zeichen das man nutzen kann ...oder man benutzt für die unterteilung der zwei set commandos etwas anderes statt den normalen Klammern!?
als workaround habe ich es z.zt. so gelöst (gefällt mir persönlich eher weniger)
if "%PROCESSOR_ARCHITECTURE%" == "x86" goto x86
set progdir=%ProgramFiles(x86)%
goto copyjob
:x86
set progdir=%ProgramFiles%
:copyjob
Vielleicht habt ihr ja noch eine Idee!?
Gruß
Dirk
Nachtrag:
folgende Zeile hat dann jetzt doch funktioniert...aber das Ergebnis ist irgendwie nicht wie erwünscht
if "%PROCESSOR_ARCHITECTURE%" == "x86" (set progdir=%ProgramFiles%) ELSE (set progdir=%ProgramFiles^(x86^)%)
der Output ist dann aber keine Variable sondern Text!
C:\>echo %progdir%
%ProgramFiles(x86)%
ich dachte das hätte ich schon mal Probiert und es hatte garnicht funktioniert...aber egal!