Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Schleife wird nicht ausgeführt und ein paar andere Kleinigkeiten

Frage Entwicklung Batch & Shell

Mitglied: Highend01

Highend01 (Level 1) - Jetzt verbinden

01.09.2007, aktualisiert 02.09.2007, 3493 Aufrufe, 7 Kommentare

Hallo zusammen,

Ich hoffe Ihr könnt mir dabei helfen, ein wenig Licht ins Dunkel der Batchprogrammierung zu bringen

Hintergrund des Scriptes ist, dass ich unter Linux zur Sicherung künftig DAR (Disk Archiver) einsetzen will und die Archive künftig zur Not auch unter Window entpacken können will und das aus Bequemlichkeit per Kontextmenü bei einem Rechtsklick auf ein solches.

Dafür wird in der Registry ein entsprechender Aufruf eingebaut:

[HKEY_CURRENT_USER\Software\Classes\Disk Archiver Image File\shell\Extract to <directory>\command]
@="\"D:\\Work\\Tools\\DAR\\dar_extract.bat\" \"%1\""

(das ist jetzt natürlich nur der <command> Teil, den Rest habe ich aus Platzgründen weggelassen. Der Aufruf des Scriptes beim Rechtsklick auf ein .dar Archiv funktioniert auch soweit korrekt.

Kommen wir zum Script:

@echo off
set sComplete=%1

for %%i in ("%sComplete%") do set sPathOnly=%%~di%%~pi
for %%i in ("%sComplete%") do set sFileNameFull=%%~ni%%~xi
for /F "delims=. tokens=1" %%i in ("%sFileNameFull%") do set sFileNameShort=%%i


REM echo sPathOnly="%sPathOnly%"
REM echo sFileNameFull="%sFileNameFull%"
REM echo sFileNameShort="%sFileNameShort%"


@rem D:\Work\Tools\DAR\glftpd_full.1.dar
@rem > /cygdrive/d/work/tools/dar/

set linPath1=%sPathOnly:\=/%
echo linPath1=%linPath1%
set linPath2=%linPath1::=%
echo linPath2=%linPath1%


@mkdir %sFileNameShort%
@rem "D:\Work\Tools\DAR\DAR.exe" -R ./ -v -w -O -x %sFileNameShort%"

---

Wenn ich einen Command Prompt mit aktivem Verzeichnis in D:\Work\Tools\DAR offen habe und das Script manuell ausführe (mit dar_extract.bat D:\Work\Tools\DAR\glftpd_full.1.dar) läuft es durch. Wenn ich es allerdings über das Kontextmenü beim Klick auf die Datei ausführe kommt es nur bis zur zweiten for Schleife.

for /F "delims=. tokens=1" %%i in ("%sFileNameFull%") do set sFileNameShort=%%i

Wird schon nicht mehr ausgeführt (getestet mit pause um zu sehen bis wo er kommt). Warum mag er die Zeile nicht und wie ändere ich sie?

Als zweites würde ich gerne wissen, wie ich die Variable sPathOnly (die beim manuellen Aufruf "D:/Work/Tools/DAR/" beinhaltet auf das Format umschreibe, was DAR voraussetzt ("/cygdrive/d/work/tools/dar/"). Meine erste Umwandlung der Backslashes in Slashes (set linPath1=%sPathOnly:\=/%) funktioniert ja noch, danach geht aber nicht mehr viel (die nächste Zeile scheitert beim Entfernen des Doppelpunktes im Pfad).

Wenn der Pfad korrekt umgeschrieben worden ist, würde ich ihn in der letzten Zeile als Variable (sPathOnly + sFileNameShort anstatt des ./ verwenden und dann das eigentlichen Entpacken damit "freischalten"... Das -x %sFileNameShort% in der Zeile setzt voraus, dass das Verzeichnis bereits existiert, weshalb auch vorher das mkdir dafür aufgerufen wird.

Das Ganze unter Windows XP (Pro).

Vielleicht hat ja jemand ein paar Hilfestellungen für mich oder auch Vorschläge, wie man so etwas intelligenter (schäm ) angehen könnte?

LG,
Highend01
Mitglied: Biber
01.09.2007 um 01:52 Uhr
Moin Highend01,

willkommen im Forum.

Den Anfang kann ich ja machen...

Bitte ändere in der Registry:
>[HKEY_CURRENT_USER\Software\Classes\Disk Archiver Image File\shell\Extract to <directory>\command]
>@="\"D:\\Work\\Tools\\DAR\\dar_extract.bat\" \"%L\""

Im Script:
01.
@echo off & setlocal 
02.
REM set sComplete=%1 
03.
@echo Just for test: [%*] 
04.
 
05.
for %%i in (%*) do set "sPathOnly=%%~dpi" 
06.
for %%i in (%*) do set "sFileNameFull=%%~nxi" 
07.
... 
08.
REM ..... hier erstmal "Pause" 
09.
Echo Debug sPathonly: [%sPathOnly%] sFileNameFull: [%sFileNameFull%] 
10.
pause 
11.
goto :eof  
12.
for /F "delims=. tokens=1" %%i in ("%sFileNameFull%") do set sFileNameShort=%%i
[Ungetestete Skizze]
Zum unteren Teil kommen wir, wenn der obere Part soweit fliegt.

Grüße
Biber,
dessen Becks wartet...
Bitte warten ..
Mitglied: Highend01
01.09.2007 um 02:15 Uhr
Hallo und danke für das Willkommen im Forum, Biber

Hab den Registry Eintrag geändert und das Script umgeschrieben:

Ausgabe beim Ausführen über die Kontextmenüerweiterung:

Just for test: ["D:\Work\Tools\DAR\glftpd_full.1.dar"]
Debug sPathonly: [D:\Work\Tools\DAR\] sFileNameFull: [glftpd_full.1.dar]
Drücken Sie eine beliebige Taste . . .

Gruß und ich hoffe das Becks ist eiskalt (<- liebt kalte Getränke) :D

LG,
Highend01
Bitte warten ..
Mitglied: Biber
01.09.2007 um 03:02 Uhr
Moin Highend01,

na ja, klappt doch schon 5 Zeilen weit... *ggg

Lass uns trotzdem nach dem Frühstück weitermachen.

Biber,
der die Praktikantinnenbetreuung sehr ernst nimmt und sich jetzt erstmal darum kümmern muss...
Bitte warten ..
Mitglied: Highend01
01.09.2007 um 03:49 Uhr
Rehuhu,

mh, schon fast 4 aber ich war irgendwie nicht müde...

Es laufen nicht nur 5 Zeilen

Bin beim Suchen über die Technet Beiträge gestolpert (http://www.microsoft.com/technet/prodtechnol/Windows2000serv/support/FA ...)

Darunter dann: How do I parse a file name parameter into its' constituent parts?

Auf diese Art und Weise konnte ich die blöde Zeile mit "FOR /F "delims=. tokens=1" %%i in ("%sFileNameFull%") DO set sFileNameShort=%%i"
rauswerfen und splitte schon mit den normalen For Schleifen die Eingangsvariable %* auf.

Ich hab noch zwei zusätzliche Aufsplittungen vorgenommen und damit ist es dann auch ein Leichtes, den für Cygwin notwendigen Pfad neu
zusammen zu setzen.

Alles in allem sieht das Script jetzt folgendermaßen aus:
01.
@echo off & setlocal 
02.
 
03.
REM Anfangsvariablen setzen 
04.
set DAR="D:\Work\Tools\DAR\DAR.exe" 
05.
set Cygdrive="/cygdrive/" 
06.
 
07.
::echo Just for test: [%*] 
08.
 
09.
REM %* in seine Bestandteile aufsplitten 
10.
for %%i in (%*) do set "sPathOnlyOld=%%~pi" 
11.
for %%i in (%*) do set "sPathFull=%%~dpi" 
12.
for %%i in (%*) do set "sFileNameFull=%%~nxi" 
13.
for %%i in (%*) do set "sFileNameShortOld=%%~ni" 
14.
for %%i in (%*) do set "sDriveLetterOld=%%~di" 
15.
 
16.
REM Pfade / Namen in den Variablen ersetzen 
17.
set sPathOnly=%sPathOnlyOld:\=/% 
18.
set sDriveLetter=%sDriveLetterOld:~0,-1% 
19.
set sFileNameShort=%sFileNameShortOld:~0,-2% 
20.
 
21.
 
22.
REM Outputs für Debugzwecke 
23.
::Echo Debug sPathOnly: [%sPathOnly%] sPathFull: [%sPathFull%]  
24.
::Echo Debug sFileNameFull: [%sFileNameFull%] 
25.
::Echo Debug sFileNameShort: [%sFileNameShort%] sDriveLetter: [%sDriveLetter%] 
26.
 
27.
REM Variable für den auf Linux Art umgeschriebenen Pfad setzen 
28.
set linPath=%Cygdrive%%sDriveLetter%%sPathOnly%%sFileNameShort% 
29.
 
30.
REM Verzeichnis erstellen und entpacken 
31.
mkdir %sPathFull%%sFileNameShort% 
32.
%DAR% -R %linPath% -w -O -x %sFileNameShort%"
Ich glaub für heute ist das schon ziemlich zufriedenstellend. Hättest du noch Verbesserungsvorschläge?

LG,
Highend01
Bitte warten ..
Mitglied: Biber
01.09.2007 um 10:58 Uhr
Moin Highend01,

<OT>
ich hatte auch nichts davon geschrieben, dass ich müde wäre oder sofort schlafen wollte...
</OT>

Verbesserungsorschläge bzw. Anmerkungen:
  • Ich habe Deinen Code in entsprechende Code-Tags gesetzt. Möglichkeiten siehe unter "Häüfige Fragen - Formatierungshilfen".

  • Bei den SET-Zuweisungen, bei denen ich immer die Set-Anweisung incl. Variablen in Anführungszeichen setze, muss ich dazu sagen: Das ist eine persönliche Vorliebe von mir, von M$ weder dokumentiert noch empfohlen. Siehe Hilfe von SET (Set /?).

  • Das Setzen der %~ni, %~xi...-Parameter kann auf jeden Fall etwas verkürzt werden. Siehe unten.

  • Und wenn gewährleitet WÄRE, dass nur ein Parameter ankommt, wäre es ganz ohne FOR-Konstrukt machbar ( set "sPathOnlyOld=%~p1"). Ich würde allerdings vor dieser Vereinfachung auf jeden Fall testen, ob es dann auch mit Parametern wie "Y:\Eigene Dateien\xy.abc" klappt, also mit Dateien, die Leerzeichen im Pfad/Namen haben.

  • bei dem sFileNameShortOld musst Du wissen, welche Konvention Du einbauen willst - entweder den "Dateinamen ohne Endung" oder den" Dateinamen bis zum ersten Punkt von links gesehen". Da ist von der ersten Version zur jetzigen ein kleine Unterschiedlichkeit.

01.
@echo off & setlocal 
02.
 
03.
REM Anfangsvariablen setzen 
04.
set DAR="D:\Work\Tools\DAR\DAR.exe" 
05.
set "Cygdrive=/cygdrive/" 
06.
 
07.
::echo Just for test: [%*] 
08.
 
09.
REM %* in seine Bestandteile aufsplitten 
10.
for %%i in (%*) do (  
11.
    set "sPathOnlyOld=%%~pi" 
12.
    set "sPathFull=%%~dpi" 
13.
    set "sFileNameFull=%%~nxi" 
14.
    set "sFileNameShortOld=%%~ni" 
15.
    set "sDriveLetterOld=%%~di" 
16.
17.
REM Pfade / Namen in den Variablen ersetzen 
18.
set sPathOnly=%sPathOnlyOld:\=/% 
19.
set sDriveLetter=%sDriveLetterOld:~0,-1% 
20.
set sFileNameShort=%sFileNameShortOld:~0,-2% 
21.
 
22.
 
23.
REM Outputs für Debugzwecke 
24.
::Echo Debug sPathOnly: [%sPathOnly%] sPathFull: [%sPathFull%]  
25.
::Echo Debug sFileNameFull: [%sFileNameFull%] 
26.
::Echo Debug sFileNameShort: [%sFileNameShort%] sDriveLetter: [%sDriveLetter%] 
27.
 
28.
REM Variable für den auf Linux Art umgeschriebenen Pfad setzen 
29.
set linPath=%Cygdrive%%sDriveLetter%%sPathOnly%%sFileNameShort% 
30.
 
31.
REM Verzeichnis erstellen und entpacken 
32.
mkdir "%sPathFull%%sFileNameShort%" 
33.
%DAR% -R %linPath% -w -O -x %sFileNameShort%
Grüße
Biber
Bitte warten ..
Mitglied: Highend01
02.09.2007 um 10:50 Uhr
Sodele, da bin ich auch wieder (sorry für die späte Rückmeldung!)

Frank, vielen lieben Dank für die Anmerkungen und ausführlichen Erklärungen!

  • Und wenn gewährleitet WÄRE, dass nur ein Parameter ankommt, wäre es ganz ohne FOR-Konstrukt machbar ( set "sPathOnlyOld=%~p1"). Ich würde allerdings vor dieser Vereinfachung auf jeden Fall testen, ob es dann auch mit Parametern wie "Y:\Eigene Dateien\xy.abc" klappt, also mit Dateien, die Leerzeichen im Pfad/Namen haben.

Ich finde die FOR-Konstruktion schon ganz in Ordnung auch wenn ich sicher sein kann, dass immer nur ein Parameter übergeben wird. Ich hatte immer nur mit einem File getestet, welches weder im Pfad noch im Namen Leerzeichen aufwies und bin dann prompt über kleinere Probleme gestolpert, als ich dann einen Pfad mit Leerzeichen genommen hab. Durch Verwendung von "" für die Variablenzuweisungen funktioniert das jetzt aber auch einwandfrei.

  • bei dem sFileNameShortOld musst Du wissen, welche Konvention Du einbauen willst - entweder den "Dateinamen ohne Endung" oder den" Dateinamen bis zum ersten Punkt von links gesehen". Da ist von der ersten Version zur jetzigen ein kleine Unterschiedlichkeit.

So wie es jetzt ist, ist es gut. DAR arbeitet automatisch mit sogenannten Slices und fängt bei der Numerierung immer mit 1 an. Da man für das Entpacken des Archives aber nicht den vollen Dateinamen inkl. Sliceendung angeben darf (dürfen schon, dann erfolgt aber eine Sicherheitsabfrage), sondern den sogenannten Basename (d.h. ohne die .SliceNummer.dar Endung), ist das Kürzen des Namens um 2 Zeichen von Hinten gesehen schon in Ordnung (nach der Aufsplittung natürlich, die dann eh schon den Dateinamen ohne Endung zurückliefert.


Eine Sache könnte ich noch brauchen: Eine Fallunterscheidung, ob das gewählte Archiv von einem lokalen Datenträger oder von einem Netzlaufwerk stammt. Die Übersetzung des Pfadnamens bei lokalen Datenträgern in die "Cygwin" Variante funktioniert ja so weit einwandfrei. Wenn man allerdings ein Archiv wählt, das auf einem Samba Share liegt, dann muss die Notation für den Pfad auf diese Weise umgesetzt werden: \\host\file\path -> \\\\host/file/path.

Eine Idee, wie man das am besten einbaut?

Abgesehen davon werden Dateinamen wohl auch eine Zeitangabe im Format %H:%M:%S beinhalten können. Da Muss ich auch noch mal prüfen, ob das Script das erkennen kann und die Doppelpunkt in ein anderes Zeichen vorher wandelt (Windows mag ja keine Doppelpunkte in Pfaden oder Dateinamen)...

LG,
Highend01
Bitte warten ..
Mitglied: Biber
02.09.2007 um 14:19 Uhr
Moin Highend01,

zu den verbleibenden Sonderfällen:
  • >Wenn man allerdings ein Archiv wählt, das auf einem Samba Share liegt, dann muss die Notation für den Pfad auf diese Weise umgesetzt werden: \\host\file\path -> \\\\host/file/path.

Da kommt uns ein zugesichertes M$-Feature zugute - die Implementierung der CMD-Funktionalität ist genauso strohdoof wie der Rest.
Bedeutet, wenn ein -ich sag mal volkstümlich- Textparameter durch den %~dpnx-Variablenauflösungsprozess gejagt wird, dann ergibt sich:
01.
Z:\> 
02.
$cmd$for /f %i in ("\\xxserver\yyshare\test.abc") do @echo [Drive:%~di] [Path:%~pi] [File:%~nxi] 
03.
[Drive:\\] [Path:xxserver\yyshare\] [File:test.abc]
----> wenn der Parameter %~di == Drive bei Dir als "\\" ankommt, dann liegt dort "\\" vor.
----> If [%sDriveLetterOld%]=="\\" set "sDriveLetterOld=\\\\"

Falls Du allerdings diesen UNC-Path noch nicht vorliegen hast, sondern erst auflösen musst, dann suche mal mit der Forumssuche nach "UNC-Pfad" oder "UNCpath.vbs".
Damit wird dann z.b. aus einem Netz-File "W:\Dokus\abc.text" das UNC-File "\\xxserver\yyshare\Dokus\abc.text" rekonstruiert.
Das wäre mit native Batch zu umständlich und zu unsauber, da sollte ein VBS-Schnipsel rein.

  • >Windows mag ja keine Doppelpunkte in Pfaden oder Dateinamen...
Stimmt, es wird immer -egal ob im Zusammenspiel mit MacOS oder mit Unix ein paar Dateinamen Konventionen geben, die Du nachbehandeln musst.
Ich würde an dieser Stelle (Windows-Namenskonventionen sicherstellen) eigentlich so vorgehen, dass der Gesamt-FullQualifiedFilename getrennt wird in einen Laufwerks/Drive-Part ("\\" bzw: "C:" etc.) und einen Part "%~pnxi" ==RestOhneDrive.
Und im RestOhneDrive kannst Du wie oben alle ":" durch "_" usw. ersetzen wie Du wutt.
Und erst danach zerlegst Du den Gesamtstring "%drive%%RestOhneDriveNachbehandelt%" in diese Pfad-, Name-, Extension-Bestandteile.

Grüße
Biber
Bitte warten ..
Neuester Wissensbeitrag
Humor (lol)

Linkliste für Adventskalender

(3)

Information von nikoatit zum Thema Humor (lol) ...

Ähnliche Inhalte
Batch & Shell
Schleife mit todos CMD

Frage von TommyDerWalker zum Thema Batch & Shell ...

Microsoft Office
gelöst Makro wird beim öffnen Vorlage nicht ausgeführt (8)

Frage von Sunny89 zum Thema Microsoft Office ...

Batch & Shell
gelöst Fehler in Schleife (2)

Frage von miczar zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Router & Routing
gelöst Ipv4 mieten (22)

Frage von homermg zum Thema Router & Routing ...

Windows Server
DHCP Server switchen (20)

Frage von M.Marz zum Thema Windows Server ...

Exchange Server
gelöst Exchange 2010 Berechtigungen wiederherstellen (20)

Frage von semperf1delis zum Thema Exchange Server ...

Hardware
gelöst Negative Erfahrungen LAN-Karten (19)

Frage von MegaGiga zum Thema Hardware ...