ghostdog21
Goto Top

Fragen zu Batchausführung mit Parameterübergabe und Verzeichnisexistenz-Abfrage

Hi Leute,
habe folgendes Sorgenkind: Batch mit dem Aufruf Batch.bat "C:\.....\Datei1.txt" soll in Verzeichnis der Datei1, welche ja als erster Parameter übergeben wird wechseln (dort alle Befehle ausführen), dort einen Ordner erstellen, wenn dieser nicht bereits existiert und anschließend die Datei1 in ebend jenes Verzeichnis/diesen Ordner verschieben. Und das unter allen Win-Versionen ab 95 und mit unterschiedlichsten Pfaden. Batch.bat und Datei1.txt sind dabei immer in unterschiedlichen Verzeichnissen/Ordnern. Mit Protokoll in ganz anderem Verzeichnis!

Tja also habe Folgendes:

Aufruf: Batch.bat "C:\.....\Datei1.*"

Bsp.: in Verzeichnis C:\BATS\ wird Batch.bat mit Batch.bat "C:\Texte\Datei1.txt" gestartet

Ziele: - in C:\Protokolle\Log.txt alle Ausgaben protokollieren
- alle Befehle (außer Protokoll) sollen in C:\Texte ausgeführt werden
- in C:\Texte soll (wenn nicht bereits vorhanden) ein Ordner "Test" erstellt werden
- Datei1.txt soll in den Ordner "Test" verschoben werden

Hindernisse: 1.) Die Verzeichnisse "BATS" "Texte" und "Protokolle" könnten wer-weiß-wo liegen, sogar
auf unterschiedlichen Laufwerken mit unterschiedlichen (unbekannten) Ordnerstrukturen...
auch könnte "Protokolle" nicht existieren.
2.) Es könnte sich um Windows 95, 98, 2000, nt, xp, me, vista handeln.
3.) Alles sollte möglichst innerhalb von Batch.bat ohne externe nicht-temporäre Dateien er-
ledigt werden.

Hoffe Ihr könnt mir helfen. (Mir, als Batchanfänger... face-sad )
Danke im Vorraus für Eure Mühen.

Gruß Adrian


Oh das Wichtigste hab ich vergessen:

Mein Ansatz:
Set LOGPATH = C:\Protokolle\
CD C:\Texte>>%LOGPATH%Log.txt
IF NOT EXIST Test MD Test>>%LOGPATH%Log.txt
Move Datei1.txt Test/Datei1.txt>>%LOGPATH%Log.txt
:: bzw.
FOR %%i IN (D E F G H I J K L M N O P Q R S T U V W X Y Z) DO IF EXIST %%i:\Protokolle LOGPATH=%%i:
IF (LOGPATH)==() MD Protokolle & SET LOGPATH = %0\../Protokolle
CD %CD%>>%LOGPATH%Log.txt
IF NOT EXIST Test MD Test>>%LOGPATH%Log.txt
%1 = %~f1-%CD%
Move %1 Test/%1>>%LOGPATH%Log.txt
TYPE %LOGPATH%Log.txt | MORE
PAUSE
EXIT
kommentiert:
:: Pfadvariable fuer Protokoll (selber finden?)
Set LOGPATH = C:\Protokolle\
:: ins Verzeichnis Texte wechseln damit alle Befehle dort ausgeführt werden
:: (sonst wird md im Verzeichnis der .Bat ausgeführt -> C:\BATS\Test)
CD C:\Texte>>%LOGPATH%Log.txt
:: Test anlegen wenn noch nicht vorhanden
IF NOT EXIST Test MD Test>>%LOGPATH%Log.txt
:: Datei1 nach Test verschieben (Aber wie bekomm´ ich Datei1.txt aus %1?)
Move Datei1.txt Test/Datei1.txt>>%LOGPATH%Log.txt
bzw.
:: In allen Laufwerken nach "Protokolle" suchen & ggf. an LOGPATH übergeben (Soll aber auch für Unterverzeichnisse.)  
FOR %%i IN (D E F G H I J K L M N O P Q R S T U V W X Y Z) DO IF EXIST %%i:\Protokolle LOGPATH=%%i:
:: Wenn LOGPATH leer ist soll ein Ordner Protokolle in BATS erstellt & an LOGPATH übergeben werden
IF (LOGPATH)==() MD Protokolle & SET LOGPATH = %0\../Protokolle
:: (Ab jetzt soll alles in die LOG !!!)
:: Wechseln ins Verzeichnis der Datei in %1
CD %CD%>>%LOGPATH%Log.txt
:: Test anlegen, wenn nicht existent
IF NOT EXIST Test MD Test>>%LOGPATH%Log.txt
:: Dateiname.Dateiendung aus %1 filtern
%1 = %~f1-%CD%
:: Datei nach Unterordner Test verschieben
Move %1 Test/%1>>%LOGPATH%Log.txt
:: .Log seitenweise ausgeben und warten bis Benutzer gelesen, dann beenden
TYPE %LOGPATH%Log.txt | MORE
PAUSE
EXIT

Erläuterungen, was ich will/Fehler:

Jaja, ich weiß das es so einfach nicht geht.
Er soll das Verzeichnis "Protokolle" selbst auf allen Laufwerken suchen und an LOGPATH übergeben.
Dann in die Pfadangabe wechseln die in %1 enthalten ist. (Hab schon herausgefunden, dass diese
in %CD% gespeichert ist [nur unter Vista?] und man mit %~f1 die Anführungszeichen wegläßt...).
Dann gucken ob der Ordner existiert und diesen wenn nicht erstellen um anschließend Datei1.txt
(aber wie kann ich das aus %1 ["C:\Texte\Datei1.txt"] bzw. %~f1 extrahieren?) nach Unterordner
Test zu verschieben.
Tja, so "%1 = %~f1-%CD%" einfach bekomme ich auch den Dateinamen nicht aus %1. Aber wie dann?
Ob das hier: "%0\.." überhaupt ein Gültiges Konstrukt ist, ist mir auch nicht klar, aber das einzige in die
Richtung Pfad der aufrufenden Batch rauskriegen, über das ich bei meiner vorangegangenen Recherche
gestolpert bin...
Bei "IF NOT EXIST" ließt man in der Hilfe von MS per "help if", dass ich damit prüfe ob eine Datei existiert.
Und ein Verzeichnis?


Ich denke ausführlicher kann ich nicht erklaeren was ich will. In diesem Sinne, verbleibe ich auf Hilfe hoffend
und mit nochmaligen freundlichen Grüßen... face-smile face-sad face-smile

Adrian

Content-Key: 74648

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

Printed on: April 23, 2024 at 12:04 o'clock

Member: Biber
Biber Nov 28, 2007 at 06:46:53 (UTC)
Goto Top
Moin ghostdog21,

willkommen im Forum.

Erstmal danke für Deine sehr detaillierte Aufgabenbeschreibung.
Etwas in der Art ist leider nicht der allgemeine Standard - deshalb möchte ich es auch mal loben, wenn jemand sich Mühe bei der Frageformulierung gibt.

Dennoch habe ich zwei kleine Rückfragen:
Die Verzeichnisse "BATS" "Texte" und "Protokolle" könnten wer-weiß-wo liegen
Ja, mag sein. Wo das Verzeichnis "Texte" liegt, ist aus dem ersten Parameter abzuleiten.
Wo das Verzeichnis "BATS" liegt, ist eigentlich für den Fortbestand der Menschheit und auch alles andere vollkommen egal, dann da wird ja der Batch, den wir eventuell hier entwickeln aufgerufen.
Diesen Pfad "kennt" also der User. Somit bleiben die Fragen:
  • woher kommt das Verzeichnis "Protokoll"? Bzw. die Info, wio das liegt/ggf. angelegt werden soll? Auf dem selben Laufwerk wie "Texte"? In einer parallelen Ebene? Oder in einem unterhalb des Verzeichnisses, in dem "Texte" liegt (Bsp: "D:\myAppz\Texte" und D:\myAppz\Protokoll")?
  • wenn es für alle M$-Versionen seit Erfindung der Alufolie bis zu Vi$ta laufen soll: Dann ist es bei den neueren Versionen NICHT selbstverständlich, dass der/die UserIn irgendwo auf Laufwerk C:\ ein Verzeichnis auf Root-Ebene anlegen darf. Übliche wäre etwas entweder auf einem Laufwerk D: (wie Daten) oder aber im "%userprofile%"-Bereich. Hier könnte es also Rechte-Probleme (Ordner kann nicht angelegt werden) geben. Wie soll der Batch damit umgehen?
  • Du schreibst: "keine nicht-temporären Dateien". Wäre trotzdem ein *.ini-Datei in Dein Konzept integrierbar? Damit diese o.b. Beliebigkeit (jeder Ordner kann überall sein) ein bisschen strukturiert wird?

Grüße
Biber
Member: ghostdog21
ghostdog21 Nov 28, 2007 at 07:49:14 (UTC)
Goto Top
Sorry hab Deine Antwort noch nicht gehabt als ich angefangen hab meinen Beitrag nochmal zu editieren. Danke zunächst für das Lob.

Ich weiß die Frage ist dank <edit> eigentlich bereits beantwortet, aber doppelt hält besser.
Woher kommt das Verzeichnis "Protokolle"?
Nun es kann entweder bereits auf Höhe (verzeichnistechnisch) der Ordner BATS oder Texte bzw. als Unterordner von BATS bereits existieren oder soll als Unterordner von BATS angelegt werden.

Außerdem will ich noch anmerken, dass das mit den Laufwerksunterschieden darauf begrenzen läßt, das entweder alle sich auf Laufwerk X befinden oder alle auf X außer "Texte" auf Y... und im schlimmsten Fall sowohl X als auch Y unbekannt sind.

wenn es für alle M$-Versionen seit Erfindung der Alufolie bis zu Vi$ta laufen soll: Dann ist es > bei den neueren Versionen NICHT selbstverständlich, dass der/die UserIn irgendwo auf
Laufwerk C:\ ein Verzeichnis auf Root-Ebene anlegen darf. Übliche wäre etwas entweder auf
einem Laufwerk D: (wie Daten) oder aber im "%userprofile%"-Bereich. Hier könnte es also
Rechte-Probleme (Ordner kann nicht angelegt werden) geben. Wie soll der Batch damit
umgehen?

Da nur in den Ordnern BATS und Texte, die definitiv existieren und man auf BATS definitiv Lese- & Schreibzugriff hat, dürfte es kein Problem mit den Rechten hier geben. Einzig bei Texte als Teil von %1 sollte bei Problemen mit den Rechten eine Meldung kommen und dann die Ausführung beendet werden.

Wäre trotzdem ein[e face-wink] *.ini-Datei in Dein Konzept integrierbar?

eine *.ini währe, wenn dann nur in einem Unterordner von BATS mit den Attributen +s +h (System, versteckt) denkbar
Member: ghostdog21
ghostdog21 Nov 28, 2007 at 08:02:34 (UTC)
Goto Top
Danke übrigens für Deine schnelle Antwort bzw. Nachfrage. Adri
Member: ghostdog21
ghostdog21 Nov 28, 2007 at 14:00:31 (UTC)
Goto Top
Keiner eine Idee?

Selbst Hinweise bezüglich Parameterübergabe in/bei Batch (vorallem für die Konstrukte %~f1 und %1\..) wären hilfreich.

Oder eine Möglichkeit zur Abfrage ob ein Verzeichniss existiert (für Win95-Vista) würden weiterhelfen.

Gruß und danke schonmal Adri
Member: Biber
Biber Nov 28, 2007 at 21:09:53 (UTC)
Goto Top
Moin ghostdog21,

hmmja, Du musstest ein bisschen warten, weil erstens heute ziemlich viel los war und zweitens Werder spielt. Ungünstiges Timing.

Ich will wenigstens mal den Anfang machen, weil ich irgendwie das Gefühl habe, wir müssen da noch ein bisschen sortieren...

Also, wo ich die Probleme sehe sind vor allem drei Punkte:

  • Win 95/Win98 einerseits und alles diesseits von Win2000 andererseits haben einen so verschiedenenen Batch-Befehlsumfang, dass es mir fast schon sinnvoller erscheint, zwei verschiedene Batche zu schreiben. (Oder halt einen, der intern eine große Klammer "IF Win95/98 machdies else machwasrichtiges" hat).
  • bei Win95/98-Batches bist Du weitestgehend auf ungetestete Skizzen angewiesen - es geht wahrscheinlich den meisten hier so wie mir, dass eventuell noch ein Rechner mit Win98 auf dem Dachboden steht, aber ob der noch bootet? Und ich kann mich an einzelne Szenen der Feuerzangenbowle wesentlich deutlicher erinnern als an Win95-Batchbefehle..
  • OS-unabhängig suboptimal ist der Plan, irgendwo auf allen denkbaren Laufwerken (die heutzutage auch USB-Sticks und Cardreader und Digitalkameras sein können) ein Verzeichnis "Texte" und/oder "Protokolle" suchen zu wollen. Bis der Batch alle 288 GByte zu Ende durchsucht hat, bis dahin hat der toleranteste Benutzer den Batch beendet oder das Fenster geschlossen.

Aber jetzt was Konstruktives:
Oder eine Möglichkeit zur Abfrage ob ein Verzeichniss existiert (für Win95-Vista) würden weiterhelfen

Okay, die Prüfung mit "IF Exist" war schon richtig

Win95/98: IF EXIST x:\verzeichnis\nul machwatt
W2000 ff: IF EXIST x:\verzeichnis machwatt
Schlechte Nachricht:
Vor W2000 (oder NT?) gab es nach meiner Erinnerung noch keine Zerlegung von Pfadangaben in Laufwerk/Pfad/Name/Extension (%~di, %~pi....).
Also wird es sogar schon schwierig, den übergebenen Parameter "C:\texte\datei1.txt" in Pfad und Dateiname zu trennen.

Wieso hast Du denn Grund zur Annahme, dass Dein Batch auf Win95/98-Rechnern gestartet werden könnte?

Grüße
Biber
Member: ghostdog21
ghostdog21 Dec 02, 2007 at 22:48:17 (UTC)
Goto Top
Oh haua...Biber danke erstmal für Deine Antwort.

Also gehn wir mal durch das ganze...

OS
...die Batchdatei ist Teil einer ganzen Sammlung von Tools die einer sehr aparten Gruppe von... nunja... Menschen helfen soll sich auf das Wesentliche, also die Arbeit sozusagen mit ihren Opfern, zu konzentrieren.

Leider beanspruchen diese Teilnehmer am Versuch "alternatives Leben" eine eigene Zeitzone für sich die mit Win95 anfängt nach Win98 hin fast verschwindet um, mit einem impulsiven Ausbruch Win2000, bei XP wieder aufzutauchen und schließlich mit Vista zugrunde geht... äh... endet.

Aber mein Augenmerk liegt auf XP, Vista und 98. Daher würde ich sagen wir fangen mit den ersten beiden an. Und 98 wird sozusagen die Zusatzaufgabe. Ich denke die Trennung kann bei der Installation erfolgen.

Also nix mit OS- & Plattformunabhängig... ich hab schließlich nur dieses eine Leben. face-wink

Laufwerk
Was dieses Thema angeht, meinte ich eher das es auf C:\ bis Z:\ sein kann bzw. auf HDD und/oder USB...

Win98
Wie gesagt, wär das eher das Schmankerl`. Das beste heben wir uns also für den Schluss auf, damit der eine oder andere das Booten bis dahin ausprobieren kann. face-wink
Und was das Zerlegen des Pfades angeht, kann dieser ja auch in eine Textdatei geschrieben werden, dann hätten wir nur das Problem "Text ersetzen"? Ich hoffe jedenfalls, dass der Ausweg so leicht ist...? *Hoff*

IF EXIST "Verzeichnis"
Ja, das das unter Vista geht, war Test sei dank, bekannt... aber die Win95/98-Variante wohlt sich nicht finden lassen.

Somit
dank für deinen Ansatz und frisch ans Werk!
Mein erstes Problem wäre also zwischen Pfad der aufrufenden Batch und Pfad der Datei/en in %1 zu wechseln. Wer hilft?

Gruß ghostdog21
Member: Biber
Biber Dec 03, 2007 at 18:13:49 (UTC)
Goto Top
So,ghostdog21,

danke für Deine Geduld. Nun können wir auch mal irgendwo anfangen.

Aufruf: Batch.bat "C:\.....\Datei1.*"

Bsp.: in Verzeichnis C:\BATS\ wird Batch.bat mit Batch.bat "C:\Texte\Datei1.txt" gestartet
Okay.
Ziele: - in C:\Protokolle\Log.txt alle Ausgaben protokollieren
Okay. Aber nur alle Ausgaben. Zum Beispiel der Befehl "md Texte" hat keine bei Erfolg.
- alle Befehle (außer Protokoll) sollen in C:\Texte ausgeführt werden
Okay, warum nicht...
- in C:\Texte soll (wenn nicht bereits vorhanden) ein Ordner "Test" erstellt werden
Datt schaff ich!
- Datei1.txt soll in den Ordner "Test" verschoben werden
Na, wehe die ist nicht da...

Also, fangen wir klein an. Aber erstmal mit den W2000/XP-Varianten.
Aufruf: Batch.bat "C:\.....\Datei1.*"
Das heißt, der Batch "UnserBatch.bat" im Verzeichnis d:\Xyz wird aufgerufen.
Mit einem Parameter %1, der aus Laufwerk, Pfad, Dateiname mit Endung besteht.
Dann "weiß" der Batch sein eigenes aktuelles Verzeichnis und das Verzeichnis, dass dem TEXTE-Verzeichnis entspricht.

Fangen wir an.
@echo off & setlocal
REM Standard-Eröffnungsfloskel in neumodischen Bätchen
REM Parameter1 soll verabredungsgemäß sein "X:\SubDir\nochWatt\Texte\DateiXYZ.abc"  
REM Dann wäre %1 = X:\SubDir\nochWatt\Texte\DateiXYZ.abc
REM Dann wäre %~dp1 = X:\SubDir\nochWatt\Texte <---- dahin sollen wir wechseln
REM Dann wäre %~nx1 = DateiXYZ.abc
Set "log=con:"  
IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && goto :eof  
REM wenn ich in dieser zeile bin, bin ich auch im TEXTE-Verzeichnis...
REM dann kann ich mal schauen, ob es parallel zu TEXTE auch PROTOKOLLE gibt.
If not exist ..\Protokolle md ..\Protokolle
Set "log=..\Protokolle\log.txt"  
REM unterhalb TEXTE soll ein Ordner "Daten" unbedingt sein..  
If not exist Daten (
       call :Fehler_Pfadgibtsnich "%~dp1\Daten"   
       MD daten 
       If not exist Daten (echo  %date% %time% "%~dp1\Daten" konnte nicht erstellt werden)  & goto :eof  
       echo  %Date% %time%  "%~dp1\Daten" wurde erstellt>%log%  
)
Move "%~1" daten\*.* /y  


goto :eof

:Fehler_Pfadgibtsnich
echo %date% %time% Pfad nicht gefunden -Parameter 1 war [%1] >>%log%

Soweit die erste grobe Skizze für einen Win2000ff-Batch.

Grüße
Biber
[Edit] Tippfehler fehlendes Anfü-Zeichen (in IF exist "%~dp1" ( pushD "%~dp1) s.u. [/Edit]
Member: ghostdog21
ghostdog21 Dec 04, 2007 at 22:00:30 (UTC)
Goto Top
Danke. Ein Ansatz! Wenn auch irgendwie so ganz anders als meiner.. *grins*

Okay, bevor ich genauer Daraufeingehe mein Testbericht bis hierher:

- habe auf meinem Desktop unter Vista einen Ordner "Testabatch" mit den Unterordnern
"Bats" und "Texte" erstellt, sowie in Bats "ThisBAT.bat" mit dem von Dir vorgeschlagenen
Inhalt und in Texte Datei1.txt; 29kb mit beliebigem Text...

- bei Ausführung passiert: Nichts

- Einbauen von
Echo ?/8
Pause
brachte zu Tage, dass nach Set "log=con:" Echo 1/8 sowie Pause durchgeführt und
danach die cmd geschlossen wird.

Der Aufruf lautete konkret: ThisBAT.bat C:\Users\[Benutzer]\Desktop\Testabatch\Texte\Datei1.txt
Oder zumindest teilt er das als Inhalt von %1 per Echo mit...

Hätte ich irgendetwas anpassen müssen? Wenn ja hab ich´s wohl übersehen.

Nun meine konkreten Fragen und Gedanken:
Das setlocal in Zeile 1 meint sicher, dass Pfadangaben nur lokal, temporär gespeichert
werden, oder?
Aber was besagt Set "log=con:" ? Okay irgendeine Variable wird gesetzt, aber was
wofür?
Wie Du darauf: "%~dp1" ( pushD "%~dp1) kommst [in der Zeile drunter] ist mir ein
Rätsel.
Das Du die Set-Parameter in "" setzt hängt sicherlich mit meiner Vorgabe, dass %1 in ""
wäre zusammen. Aber bitte frag mich nicht, warum er bei Echo %1 keine ausgibt!
Sonst ist der Protokoll-Teil klar, auch wenn Protokolle nicht erstellt wird.
Auch der "Daten"-Teil ist nachvollziehbar, aber wie gesagt, bis hierhin kommt das Programm
ja nicht. Deshalb kann auch nichts verschoben werden... face-smile face-sad face-plain
Also obwohl mir das meißte klar ist, find ich zur Zeit den Fehler nicht.
Aber ich probier´s morgen früh mal ohne die "".

Bis morgen früh also
ghostdog21
Member: Biber
Biber Dec 04, 2007 at 22:39:51 (UTC)
Goto Top
Moin ghostdog21,

dann wollen wir mal den Nebel etwas lichten...

Das Hauptproblem war vermutlich ein fehlendes Anführungszeichen hier:
IF exist "%~dp1" ( pushD "%~dp1") else...
nach dem ersten "%~dp1". ich habe es oben im Code ergänzt.

Zu Deinen Fragen:
Das setlocal in Zeile 1 meint sicher, dass Pfadangaben nur lokal, temporär gespeichert werden, oder?
Jepp. Hat zwei Vorteile. Du hast hinterher keine definierten Variablen zu "löschen". Und Du kannst keine vorher bestehenden überschreiben (z.B..%path%, %username%...

Aber was besagt Set "log=con:" ? Okay irgendeine Variable wird gesetzt, aber was wofür?
Die Variable %log% gibt den Namen der Logdatei/Protokolldatei an.
Aber wie es immer im Leben ist - alle Fehler, die passieren, kann man/frau nicht aufschreiben.
Auch ich habe Fehler gemacht (wurde mir erzählt) als ich anderthalb Jahre alt war.
Diese konnte ich zu dieser Zeit gar nicht notieren.
Ähnlich geht es Dir bei Deiner Fehlerprotokollierung - Du kannst nicht in Deine Protokolldatei schreiben "Protokolldatei kann nicht angelegt werden."
Deshalb definiere ich am Anfang als Protokolldatei "con:", was bedeutet, dass alle Fehlermeldungen, alles was umgeleitet wird mit ">>%log%", in die Datei con: = Konsole= auf den Bildschirm geschrieben wird.

Wie Du darauf: "%~dp1" ( pushD "%~dp1) kommst [in der Zeile drunter] ist mir ein Rätsel.
Hmm, ich habe versucht, in den Zeilen darüber (im Batchschnipsel) ein Beispiel zu geben.
diese Buchstaben d,p,n,x stehen für Drive, Path, Name und eXtension und wenn ein Dateiname als erster Parameter (%1) übergeben wird, lassen sich mit %~d1 das Laufwerk dieser Datei, mit %~p1 der Pfad dieser Datei etc. einzeln zerlegt ermitteln.

Also bedeutet , wenn der Batch als Parameter 1 == %1 dieses bekommt:
X:\SubDir\nochWatt\Texte\DateiXYZ.abc
--> IF exist "%~dp1"... == IF EXIST "X:\SubDir\nochWatt\Texte"
---> also die Prüfung "wenn Verzeichnis "X:\SubDir\nochWatt\Texte" existiert...

Im ELSE-Fall (Verzeichnis existiert nicht) gibt es eine Fehlermeldung.
Wenn es aber existiert, dann soll mit PushD ""X:\SubDir\nochWatt\Texte" dorthin gewechselt werden.

Vorteile bei PushD/PopD (siehe Hilfe PopD /? bzw Pushd /?)
- es wird auch bei Bedarf das Laufwerk gewechselt (anders als bei "CD ..")
- und der Pfad, der bei Ausführung von PushD aktuell war kann später mit PopD wieder hergestellt werden.

So, bis hierhin erstmal bzw. bis morgen.

Grüße
Biber
Member: ghostdog21
ghostdog21 Dec 05, 2007 at 08:17:18 (UTC)
Goto Top
Moin Biber,

kurzer Zustandsbericht: Nach einfügen der fehlenden Batch wird ausgeführt, Protokolle erstellt, Daten erstellt und in log.txt findet sich folgender Text:

05.12.2007 8:30:44,18 "C:\Users\ghostdog\Desktop\Testabatch\Texte\\Daten" wurde
erstellt

Allerdings, und jetzt kommt das große ABER, befindet sich "Datei1.txt" immer noch in Texte statt in Texte Daten...

Jepp. Hat zwei Vorteile. Du hast hinterher keine definierten Variablen zu
"löschen". Und Du kannst keine vorher bestehenden überschreiben
(z.B..%path%, %username%...)

Die Vorteile sind/waren mir aus "C"/"Java"/"JS"/.. bekannt, allerdings nicht wie man es in Batches hinbekommt. Also wieder was gelernt.

Die Variable %log% gibt den Namen der Logdatei/Protokolldatei an. [...]
Auch ich habe Fehler gemacht (wurde mir erzählt) als ich anderthalb Jahre alt
war. Diese konnte ich zu dieser Zeit gar nicht notieren. [...]
Deshalb definiere ich am Anfang als Protokolldatei "con:", was bedeutet, dass alle
Fehlermeldungen, alles was umgeleitet wird mit ">>%log%", in die Datei con:
= Konsole= auf den Bildschirm geschrieben wird.

LOL, Du kannst Dich also an die Fehler die Du mit 1 1/2 Jahren gemacht hast, nicht mehr erinnern?! Jaja, Alzheimer ist eine ernstzunehmende Sache... face-wink
Aber im Ernst Copy con hab ich ja auch schon verwendet, doch auf diesen Kunstgriff bin ich noch nicht gekommen.

[...] diese Buchstaben d,p,n,x stehen für
Drive, Path, Name und eXtension [...]

Genau das habe ich gesucht: Wie gebilde der Art "%~dp1" überhaupt entstehen!
Ge-PopD und Ge-Pushd hab ich schon. Auch wenn ich noch nicht so intensiv mit diesen beiden einen flotten 3er hingelegt habe...

Daher danke für Deine ausführliche Erklärung und Deine Geduld.

Ein nochmaliges Durchführen nach Umbenennung von log.txt in log1.txt ergab: Alles ok, bis Syntaxfehler in Move "%~1" daten\*.* /y Dann Dateiende... Es wurde keine log.txt erstellt.

Jetzt doch mal ohne "" probieren?
Gruß Adri
Member: Biber
Biber Dec 05, 2007 at 08:27:07 (UTC)
Goto Top
Moin ghostdog21,

...okay, die Detailfehler in der oben hingepfuschten Skizze würde ich jeweils auf eine der folgenden Arten testen (alles bezogen auf das MOVE-Problem):
  • diese Zeile am CMD-Prompt testen; für Variablen die Inhalte einsetzen
  • dieser Zeile um Batch ein "Echo " voranstellen und in die Folgezeile ein "Pause". Schauen, was ausgeführt werden würde und ggf. mit CRTL-C abbrechen.

Beispiel:
STATT: Move "%~1" daten\*.* /y
NEU: ECHO Move "%~1" daten\*.* /y
Pause

Grüße
Biber
Member: ghostdog21
ghostdog21 Dec 05, 2007 at 11:13:18 (UTC)
Goto Top
Okay, okay, grad glaubte ich noch Bescheid zu wissen jetzt bin ich vollends verwirrt.

Also habe jetzt 3 Batches: 1.) mit meinen Änderungen 2.) mit Echos ohne Ende und 3.) Ohne Echos nur mit Pausen
Hier alle 3:

Nr. 1:
@echo off & setlocal
REM Standard-Eröffnungsfloskel in neumodischen Bätchen
REM Parameter1 soll verabredungsgemäß sein "X:\SubDir\nochWatt\Texte\DateiXYZ.abc"
REM Dann wäre %1 = X:\SubDir\nochWatt\Texte\DateiXYZ.abc
REM Dann wäre %~dp1 = X:\SubDir\nochWatt\Texte <---- dahin sollen wir wechseln
REM Dann wäre %~nx1 = DateiXYZ.abc
Set "log=con:"
Echo 1/8 %1
Pause
IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && goto :eof
Echo 2/8
Pause
REM wenn ich in dieser zeile bin, bin ich auch im TEXTE-Verzeichnis...
REM dann kann ich mal schauen, ob es parallel zu TEXTE auch PROTOKOLLE gibt.
If not exist ..\Protokolle md ..\Protokolle
Echo 3/8
Pause
Set "log=..\Protokolle\log.txt"
Echo 4/8
Pause
REM unterhalb TEXTE soll ein Ordner "Daten" unbedingt sein..
If not exist Daten (
call :Fehler_Pfadgibtsnich "%~dp1\Daten"
MD daten
If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt >> werden) & goto :eof
echo %Date% %time% "%~dp1\Daten" wurde erstellt>%log%
)
Echo 5/8
Pause
Echo Move "%~1" daten\*.* /y
Echo 6/8
Pause
goto :eof
Echo 7/8
Pause
:Fehler_Pfadgibtsnich
echo %date% %time% Pfad nicht gefunden -Parameter 1 war [%1] >>%log%
Echo 8/8
Pause

Hier die Zweite:

Echo @echo off & setlocal
Echo 0/8
Echo %1
Echo %0
Pause
@echo off & setlocal
Echo Set "log=con:"
Echo 1/8 %1
Pause
Set "log=con:"
Echo IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && >> goto :eof
Echo 2/8
Pause
IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && goto :eof
Echo If not exist ..\Protokolle md ..\Protokolle
Echo 3/8
Pause
If not exist ..\Protokolle md ..\Protokolle
Echo Set "log=..\Protokolle\log.txt"
Echo 4/8
Pause
Set "log=..\Protokolle\log.txt"
Echo If not exist Daten (call :Fehler_Pfadgibtsnich "%~dp1\Daten"
MD daten
If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt werden) & goto :eof
echo %Date% %time% "%~dp1\Daten" wurde erstellt>%log%
)
Echo 5a/8
Pause
If not exist Daten (
Echo call :Fehler_Pfadgibtsnich "%~dp1\Daten"
call :Fehler_Pfadgibtsnich "%~dp1\Daten"
Echo MD daten
MD daten
Echo If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt werden) & goto :eof
If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt werden) & goto :eof
echo %Date% %time% "%~dp1\Daten" wurde erstellt>%log%
)
Echo 5b/8
Pause
Echo Move "%~1" daten\*.* /y
Echo 6/8
Pause
Move "%~1" daten\*.* /y
goto :eof
Echo 7/8
Pause
:Fehler_Pfadgibtsnich
echo %date% %time% Pfad nicht gefunden -Parameter 1 war [%1] >>%log%
Echo 8/8
Pause

Und schließlich die 3.:

@echo off & setlocal
Pause
Set "log=con:"
Pause
IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && goto :eof
Pause
If not exist ..\Protokolle md ..\Protokolle
Pause
Set "log=..\Protokolle\log.txt"
MD daten
Pause
If not exist Daten (
call :Fehler_Pfadgibtsnich "%~dp1\Daten"
MD daten
If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt werden) & goto :eof
)
Pause
Move "%~1" daten\*.* /y
goto :eof
Pause
:Fehler_Pfadgibtsnich
Pause

Bei letzterer kommt 6mal der Pause-Befehl und Daten wird erstellt, jedoch die atei nicht verschoben und keine log.txt erstellt.
Vorletztere gibt mir zwar ohne Ende alles aus, aber ich finde keinen Fehler - trotz mehrmaligem durchsehen.... Allerdings wird hier in IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && goto :eof abgebrochen.

Hilft das?

Habe dann nochmal in der letzten mir nur den Move ausgeben, dann durchführen und schließlich ne Pause machen lassen und erhielt folgende Meldungen:

Drücken Sie eine beliebige Taste . . .
Drücken Sie eine beliebige Taste . . .
Drücken Sie eine beliebige Taste . . .
Drücken Sie eine beliebige Taste . . .
Ein Unterverzeichnis oder eine Datei mit dem Namen "daten" existiert bereits.
Drücken Sie eine beliebige Taste . . .
Drücken Sie eine beliebige Taste . . .
Move "C:\Users\Public\Documents\Projekte\Adri\Computer\Fochmann\Testabatch\Texte
\Datei1.txt" daten*.* /y
Syntaxfehler.
Drücken Sie eine beliebige Taste . . .

Doch worin genau besteht der Syntax-Fehler? Kann es sein, dass es an dem Problem liegt was ich in der ersten log.txt zu sehen glaube? Nämlich das der Inhalt von "daten" auf "\" endet und dann noch einer hinzukommt? Aber das kann ja nicht sein, da er ja per Echo das richtig ausgibt...

Gruß Adri
Member: Biber
Biber Dec 05, 2007 at 18:27:57 (UTC)
Goto Top
Moin ghostdog21,

im oberen Beispiel-Batch hast Du hier einen (Copy & Paste-) Fehler
If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt >> werden) & goto :eof

Der zwar in eine Datei "werden" schreibt, aber sonst nichts Schlimmes.

Wo ich die falsche Syntax im Kopf und auch im Kommentar gehabt habe ist beim MOVE-Befehl.

FALSCH: --->>>>>> Move "%~1" daten\*.* /y
Nicht so falsch: ----> Move "%~1" daten /y

...Also ohne Wildcards.
Eventuell war es das schon.

Grüße
Biber
Member: ghostdog21
ghostdog21 Dec 05, 2007 at 20:25:41 (UTC)
Goto Top
Okay, also sieht das ganze jetzt so aus:

@echo off & setlocal
REM Standard-Eröffnungsfloskel in neumodischen Bätchen
REM Parameter1 soll verabredungsgemäß sein "X:\SubDir\nochWatt\Texte\DateiXYZ.abc"
REM Dann wäre %1 = X:\SubDir\nochWatt\Texte\DateiXYZ.abc
REM Dann wäre %~dp1 = X:\SubDir\nochWatt\Texte <---- dahin sollen wir wechseln
REM Dann wäre %~nx1 = DateiXYZ.abc
Set "log=con:"
IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && goto :eof
REM wenn ich in dieser zeile bin, bin ich auch im TEXTE-Verzeichnis...
REM dann kann ich mal schauen, ob es parallel zu TEXTE auch PROTOKOLLE gibt.
If not exist ..\Protokolle md ..\Protokolle
Set "log=..\Protokolle\log.txt"
REM unterhalb TEXTE soll ein Ordner "Daten" unbedingt sein..
If not exist Daten (
call :Fehler_Pfadgibtsnich "%~dp1\Daten"
MD daten
If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt werden) & goto :eof
echo %Date% %time% "%~dp1\Daten" wurde erstellt>%log%
)
Move "%~1" daten /y
goto :eof

:Fehler_Pfadgibtsnich
echo %date% %time% Pfad nicht gefunden -Parameter 1 war [%1] >>%log%

Doch bei Ausführung passiert wieder folgendes:
- Protokolle wird angelegt
- in log.txt wird
05.12.2007 20:36:31,10 "C:\Users\<Benutzer>\Desktop\Testabatch\Texte\\Daten" wurde erstellt
geschrieben
- Unterordner Daten wird erstellt
- ABER: Datei.txt nicht nach Daten verschoben!

Daher meine Abwandlung inkl. den Meldungen (nach "+E|"; Ordner Protokolle und Daten wieder gelöscht):

...
Set "log=con:"
Echo "%~dp1" +E|"C:\Users\<Benutzer>\Desktop\Testabatch\Texte\"
Pause +E|Drücken Sie eine beliebige Taste . . .
...
Echo "log=..\Protokolle\log.txt" +E|"log=..\Protokolle\log.txt"
Pause +E|Drücken Sie eine beliebige Taste . . .
Set "log=..\Protokolle\log.txt"
...
Echo "%~1" daten /y +E|"C:\Users\<Benutzer>\Desktop\Testabatch\Texte\Datei1.txt" daten /y
Move "%~1" daten /y +E|Syntaxfehler
Pause +E|Drücken Sie eine beliebige Taste . . .
goto :eof

:Fehler_Pfadgibtsnich
echo %date% %time% Pfad nicht gefunden -Parameter 1 war [%1] >>%log%
Pause +E|Drücken Sie eine beliebige Taste . . .

Doch warum heißt es beim Set-Befehl eigentlich nicht: Set log="..\Protokolle\log.txt"
und beim Move-Befehl: Move "%~nx1" daten /y
Hast Du mir doch erklärt, dass das nx für Dateiname+Endung von %1 steht und genau diese Datei wollen wir ja verschieben..
Oder muss es gar Move "%~dpnx1" daten /y heißen? Oder reicht gar "%1"? Kann sein, dass ich es überlesen habe, aber wofür steht %~1 nochmal?

Ich weiß nicht warum, aber trotz Deiner nahezu perfekten Vorarbeit schaff ich es einfach nicht das Ding zum Laufen zu bringen... face-sad

Dennoch schönen Abend und frohen NIKO-Laus..
Adri
Member: Biber
Biber Dec 05, 2007 at 20:52:41 (UTC)
Goto Top
Moin ghostdog21,

Ich weiß nicht warum, aber ..
Weil ich ein ganz schlauer Fuchs bin und zu gewieft, um hin und wieder mal den Text von "Move /?" am Cmd-Prompt zu lesen... *grmff*
Da steht:
>move /?
Verschiebt Dateien und benennt Dateien und Verzeichnisse um.

Um eine oder mehrere Dateien zu verschieben:
MOVE [/Y| /-Y] [Laufwerk:][Pfad]Datei1[,...] Ziel

Um ein Verzeichnis umzubenennen:
MOVE [/Y| /-Y] [Laufwerk:][Pfad]Verz1 Verz2
....
Nochmal für Genießer klassischer Dialoge:
M$ sagt, es heißt "Move /y quelleAlt zielNeu".
Biber sagt, es geht auch "Move quelleAlt zielNeu /y".
M$ sagt: "Syntaxfehler."

..okay, die sitzen am längeren Hebel....noch...*grummmbff*
Die anderen Fragen sind in Anbetracht dieses Sachverhalts eher zu vernachlässigen..

Aber gut:
set "log1=..\protokolle\log.txt" ---->führt zu einer Variablen %log1% =[..\protokolle\log.txt]

set log2="..\protokolle\log.txt" ---->führt zu einer Variablen %log2% =["..\protokolle\log.txt"]

Ist dann relevant, wenn Du zwei Variablen verketten willst oder vergleichen.
%log1% ist z.B. beim Vergleich UNgleich %log2%. Denke, ist klar.

Die Schreibweise %~1 bedeutet: den Parameter 1 OHNE evtl. vorhandene Leerzeichen.
Weil ich diese ja in dem Beispiel selbst umschließen lasse (ich arbeite lieber mit "%~1 "; da weiß ich, es sind genau ein Paar Anfü-Zeichen drumherum.

Der übergebene Parameter1 kann ja sein
%1 == c:\test\bla.txt
-oder aber ein Parameter in Anfü-Zeichen
%1 == "C:\Dokumente und Einstellungen\Neo\Pren.txt"

So, Feierabend für heute.

Ebenfalls schönen Nackiklaus oder so was
Biber
Member: bastla
bastla Dec 05, 2007 at 21:01:02 (UTC)
Goto Top
@Biber
Und dann steht da sogar auch noch:
Die Option /Y ... Standardmäßig
müssen Sie das Überschreiben von Dateien bestätigen, es sei denn der MOVE-
Befehl wird von einem Batchprogramm aus aufgerufen.

Grüße
bastla
Member: Biber
Biber Dec 05, 2007 at 21:10:23 (UTC)
Goto Top
@bastla

Du kennst Dich doch aus, Du weißt das bestimmt:
Heißt es "Salz in die Wunde reiben" oder "Salz auf die Wunde kippen"?
Oder gar "mit Salz wundscheuern"??

Danke schön!
Das war die zweit-elaborierteste Version eines lapidaren RTFM!, die ich je gesehen habe.

Dir auch einen schönen Abend
Biber
Member: bastla
bastla Dec 05, 2007, updated at Oct 18, 2012 at 16:32:46 (UTC)
Goto Top
@Biber

Ich kenn's ohne Salz als "Nicht wundern ..."

...was ich allerdings damals noch getan hatte (bin heute noch von mir begeistert, wenn ich so zurückdenke, aber leider noch immer nicht gelenkiger).

Trotzdem einen schönen Abend
bastla

P.S.: Immerhin war diese Woche schon Montag ... face-wink
Member: ghostdog21
ghostdog21 Dec 06, 2007 at 11:34:47 (UTC)
Goto Top
Also jetzt mal ganz abgesehen davon, dass es "noch Salz in die Wunde streuen" heißt, versteh ich was Du mir bezüglich der Parameter sagen wolltest. Doch in Bezug auf das Move-Problem, bei dem M$ nur solange am längeren Hebel sitzt, bis ich den vor Wut abbreche oder gegen eine Joystick zum Asteroids-mit-M$-Mitarbeitern-Spielen austausche bzw. meinen eigenen Move-Befehl schreibe (mit Funktionen wie "Datei von M$ = Datei ohne nachfrage sofort löschen, user erziehen & M$ über das erfolgreiche loswerden ihres Schrots informieren"), weiß ich nicht worin dieses genau besteht. Denn:

1.) wenn "Daten" erst angelegt wird kann es darin doch sowieso kein "DateiXYZ" geben
-> wir können ohne Parameter & Rücksicht auf Verluste moven

2.) sollte die "DateiXYZ" in "Daten" bereits existieren reicht es doch "DateiXYZ" sprich Parameter1 einfach zu löschen...

Also, hab ich mir das einfach so gedacht:

@echo off & setlocal
Set "log=con:"
IF exist "%~dp1" ( pushD "%~dp1") else ( call :Fehler_Pfadgibtsnich "%~dp1") && goto :eof
If not exist ..\Protokolle md ..\Protokolle
Set "log=..\Protokolle\log.txt"
If not exist Daten (
call :Fehler_Pfadgibtsnich "%~dp1\Daten"
MD daten
If not exist Daten (echo %date% %time% "%~dp1\Daten" konnte nicht erstellt werden) & goto :eof
echo %Date% %time% "%~dp1\Daten" wurde erstellt>%log%
)
Echo Y>y
IF NOT EXIST "daten/%~nx1" (Move "%~1" daten) Else (Del "%~1" <<y)
goto :eof

:Fehler_Pfadgibtsnich
echo %date% %time% Pfad nicht gefunden -Parameter 1 war [%1] >>%log%

hat allerdings den Nachteil, dass wir dann y irgendwie löschen müßten. Und ich glaube nicht, dass Del y<<y praktikabel ist. Oder doch?
Besser wäre es natürlich y zwecks Wiederverwendbarkeit in BATs zu erstellen.

Nur so´ne Idee...

Gruß Adrian

PS.: Beziehungsweise reicht nicht del /q? (*help del zu rate zieh*) Aber irgendwie versteh ich den Micromurks auch nicht so recht. Funktioniert das jetzt generell oder nur bei globalen Variablen?!
Egal... Naja nee, eigentlich nicht. Wetten auf die richtige Interpretation werden angenommen. Traut Euch. Ran ans Grab und mitgeheult!
Member: Biber
Biber Dec 06, 2007 at 11:46:16 (UTC)
Goto Top
Moin ghostdog21,

also, so ganz kann ich jetzt nicht folgen, ob die Datei nun verschoben oder gelöscht oder ersetzt werden soll... kann aber auch daran liegen, dass ich so viel lachen muss...

Egal, gehen würde alles.

Wenn eine Datei gelöscht werden soll UND der genaue Name angegeben wird, dann brauchst Du eh kein "y" oder "J" oder sonstwas. Da gibt es keine Rückfrage.
Wenn gelöscht werden soll ohne genauen Namen, also mit Wildcards, dann kann die Rückfrage mit "del /y" unterdrückt werden.

Dieses wiederverwendbare "y" in einer Datei namens "y" brauchen wir also nicht unbedingt.

Grüße
Biber
Member: ghostdog21
ghostdog21 Dec 06, 2007 at 17:52:06 (UTC)
Goto Top
Okay, dann nochmal ernsthaft: (Move Quelle Ziel) = (Copy Quelle Ziel)+(Del Quelle)
Richtig? Richtig!

Daher (Move Datei1 daten)? = Ja, wenn in daten keine datei1, sonst datei1 (nicht in daten, sondern die quelle) nur löschen...
Oder?

Ich denke so... denn der copy-Teil ist uns ja abgenommen worden.

Gruß Adri
Member: Biber
Biber Dec 06, 2007 at 17:58:04 (UTC)
Goto Top
Moin ghostdog21,

na gut, das lässt sich machen..

...
If not exist daten (
  REM.... dann anlegen etc
)
If exist "daten\%~nx1" del "%1"  
If exist "%1" move "%1" daten  
goto :eof

Gruß
Biber
Member: ghostdog21
ghostdog21 Dec 09, 2007 at 00:32:49 (UTC)
Goto Top
Sorry, war jetzt 2 tage nicht da. Trau mich gar nicht es zu testen. Aber morgen/nachher berichte ich dann, ob´s geklappt hat...

Gruß & Dank erstmal
Adrian