ajintaro
Goto Top

FTP Vorgang mittels Batch Datei automatisieren

Guten Morgen liebe Administrator.de Member. Ich bin gerade eben hier reingestolpert face-smile

Ich habe mich bemueht die Foren- und Googlesuche zu nutzen bevor ich euch mit meinem Problem belaestige. Allerdings konnte ich mein Problem nur zum Teil loesen und erhoffe mir einige Tipps von euch. Die problemstellung ist sicherlich nichts neues: taeglich wird ein file auf einem Sun Server erzeugt, welches ich taeglich auf meinem Win XP PC lokal sichern muss. Das muss ich nun Tag fuer Tag machen... ich bin mir sicher dass man soetwas automatisieren kann. Ich versuche diesen Post so angenehm wie moeglich zu verfassen.

Ich moechte euch nun erstmal ein paar Detailinformationen zur Situation geben, dann meine bisherigen Loesungsansaetze.

(1) DIE SITUATION

Der Sun-Server hat in einem Verzeichnis dutzende *.zip-Dateien:
ABC-goo-100816.zip
ABC-goo-100817.zip
ABC-goo-100818.zip
ABC-goo-100819.zip
ABC-goo-100820.zip

An jedem Tag kommt eine weitere Datei hinzu. Morgen dementsprechend ABC-goo-100821.zip.
Ich moechte jeden Morgen die neuste Datei vom Server herunterladen - dabei gilt zu pruefen ob die Datei nicht schon bei mir lokal vorhanden ist.

(2) MEIN LOESUNGSANSAETZE

Eine Mischung aus Batch File und FTP sollte mein Anliegen loesen. Zunaechst wollte ich wissen, in wie weit mir FTP entgegen kommen kann. Ich bin leider kein Admin-crack und kenne nur Standard Befehle. Ich habe eine test.ftp Datei geschrieben mit folgendem Inhalt:

OPEN sunserver.geheim.de
horst
uschi
CD 123/DatenTrak/Zip

Aufgerufen wir das mit einer Batch Datei:

ftp -s:vtc.ftp

Soweit so gut. Ich connecte mich auf den Sunserver und bin im richtigen Verzeichnis. Wenn ich nun den Befehl dir *.zip eingebe bekomme ich alle .zip Dateien aufgelistet. Der Befehl ls -ltr sortiert alle Dateien nach Datum (absteigend). Eine Kombination beider Befehle ist imho nicht moeglich... ich hab viel ausprobiert aber ich habe es nicht geschafft, dem FTP eine Liste der neusten .zip Dateien zu entlocken.

Also wollte ich folgenden Trick anwenden: mittels ls *.zip > output.txt erhalte ich dann eine Textdatei mit dem inhalt:

ABC-goo-100816.zip
ABC-goo-100817.zip
ABC-goo-100818.zip
ABC-goo-100819.zip
ABC-goo-100820.zip

Nun waere es doch toll, wenn eine weitere (oder die selbe) batch Datei diese Ergebnisdatei durchwuehlt und mir (abhaengig vom aktuellen Datum) ABC-goo-100820.zip ausspuckt. Damit kann ich dann eine weitere FTP Session starten und die Datei ziehen. Das wuerde mir schon extrem weiterhelfen. Allerdings ist Batch-Programmierung wasa fuer Halbgoetter.... und definitiv zu schwierig fuer mich.

Ein epischer Text und ein kniffliges Problem. Wisst ihr Rat?

Content-Key: 149391

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

Ausgedruckt am: 29.03.2024 um 12:03 Uhr

Mitglied: 60730
60730 20.08.2010 um 11:04:53 Uhr
Goto Top
Moin und willkommen..

[OT]
Horst und Uschi - ich vermute du bist mir sympathisch face-wink
[/OT]

Such mal nach FTP & Batch, da wirst du so einiges finden, was zu deiner Aufgabe passt.

Ich würde allerdings nicht das Datum heranziehen - denn lief aus Grund xyz an einem Tag die Batch nicht - fehlt dir die zip aus diesem Tag.

Eher - so wie du es angedacht hast und wir schon so realisiert haben:

via ls *.zip eine Liste aller Dateien auf dem FTP und via dir /B *.zip auf dem Horst von der Uschi.
Alles was im FTP und nicht auf dem lokalen Uschihorst liegt saugen...


Oder ganz andreaskreuzherum...

Nimm WGET und dort den parameter -n
wget.exe -Y -N -i C:\meineliste-aller_zips_auf_dem_ftp.txt -P C:\mein_lokaler_Ziel_Ordner\
Gruß
Mitglied: Friemler
Friemler 20.08.2010 um 20:41:18 Uhr
Goto Top
Hallo Ajintaro,

hier ein Vorschlag zur Lösung Deines Problems. Da ich keinen schreibenden Zugriff auf einen FTP-Server habe, konnte ich keine Test-Dateien erzeugen um das Skript komplett zu testen. Bei Fehlfunktionen bitte Rückmeldung geben.
@echo off

setlocal

cls

set "FTPGetDir=%TEMP%\ftpcmd.txt"  
set "FTPGetFile=%TEMP%\ftpcmd.txt"  
set "FTPServer=ftp.dein_server"  
set "Usr=horst"  
set "Pwd=uschi"  
set "RemoteDir=123/DatenTrak/Zip"  
set "FileType=zip"  
set "RemoteDirList=%TEMP%\FileList.txt"  
set "LocalRepository=DeinZielOrdner"  


del "%RemoteDirList%" 2>NUL  


echo Hole Verzeichnis %RemoteDir% vom FTP-Server
echo.

> "%FTPGetDir%" echo open %FTPServer%  
>>"%FTPGetDir%" echo user %Usr% %Pwd%  
>>"%FTPGetDir%" echo cd "%RemoteDir%"  
>>"%FTPGetDir%" echo ls -ltr "%RemoteDirList%"  
>>"%FTPGetDir%" echo bye  

ftp -n -s:"%FTPGetDir%"  
del "%FTPGetDir%"  
echo.


call :GetDate
set "dat=%errorlevel%"  


echo Suche in Verzeichnis %RemoteDir% nach Datei vom %date% ...

for /f "usebackq tokens=9,*" %%f in ("%RemoteDirList%") do (  
  if "%%g" neq "" (  
    call :ProcessFilename "%%f %%g" %dat% && (echo Gefunden & echo. & call :CopyFile "%%f %%g" & exit /b)  
  ) else (
    call :ProcessFilename "%%f" %dat% && (echo Gefunden & echo. & call :CopyFile "%%f" & exit /b)  
  )
)

echo Nicht gefunden
echo.

exit /b



:ProcessFilename
setlocal

if /i "%~x1" neq ".%FileType%" exit /b 1  

set "fname=%~1"  
set "dat=%2"  

for /f "tokens=3 delims=-." %%f in ("%fname%") do (  
  if "%%f" equ "%dat%" (  
    exit /b 0
  )
)

exit /b 1



:CopyFile
setlocal

if exist "%LocalRepository%\%~1" (  
  echo Datei %~1 wurde schon vom FTP-Server geladen.
  echo.
  exit /b
)

echo Hole Datei %~1 vom FTP-Server
echo.

> "%FTPGetFile%" echo open %FTPServer%  
>>"%FTPGetFile%" echo user %Usr% %Pwd%  
>>"%FTPGetFile%" echo binary  
>>"%FTPGetFile%" echo cd "%RemoteDir%"  
>>"%FTPGetFile%" echo get "%~1" "%LocalRepository%\%~1"  
>>"%FTPGetFile%" echo bye  

ftp -n -s:"%FTPGetFile%"  
del "%FTPGetFile%"  
echo.

exit /b



:GetDate
setlocal enabledelayedexpansion

for /f "tokens=1-3 delims=." %%d in ("%date%") do set "dat=%%f%%e%%d"  
set "dat=%dat:~-6%"  

exit /b %dat%


back-to-topVoraussetzungen

  • Das Muster, nach dem die Dateinamen aufgebaut sind, muss so, wie in Deiner Aufgabenstellung beschrieben, sein: Der Dateiname besteht aus drei Gruppen alphanumerischer Zeichen, die durch ein Minuszeichen getrennt sind. Das Minuszeichen darf in keiner der drei Gruppen vorkommen. Die letzte Gruppe stellt das Datum im Format YYMMDD dar, danach kommt optional ein Punkt und der Dateityp.

  • Der FTP-Server sollte immer erreichbar sein. Das Skript zeigt die Ausgaben des FTP-Befehls und damit auch die Fehlermeldungen zwar an, Du musst dann aber selbst auf Fehlermeldungen achten (z.B. beim CD-Befehl Verzeichnis nicht gefunden).


back-to-topErklärung

In den Zeilen 7-15 werden sämtliche Einstellungen für das Skript festgelegt.
  • FTPGetDir und FTPGetFile geben Pfade zu temporären Dateien an, in die die FTP-Skripte geschrieben werden.

  • FTPServer ist die Adresse des Servers, Usr der Benutzername und Pwd das Passwort für die Anmeldung. RemoteDir ist das Verzeichnis auf dem Server, das ausgelesen werden soll.

  • FileType gibt den Typ der Dateien an, die von dem Skript verarbeitet werden sollen.

  • RemoteDirList ist die Datei auf Deinem lokalen Rechner, in die das Listing des Server-Verzeichnisses geschrieben wird.

  • LocalRepository gibt den Pfad zum Speicherort der Dateien an, die Du jeden Tag vom Server laden willst.

Da die Datei RemoteDirList am Ende des Skripts nicht gelöscht wird, wird das am Anfang in Zeile 18 gemacht. So wird kein Datenmüll aus dem letzten Skriptlauf verarbeitet, falls der FTP-Server mal nicht erreichbar sein sollte.

In Zeile 24-28 wird das temporäre FTP-Skript erzeugt um das Verzeichnis auf dem FTP-Server einzulesen. Durch Zeile 30 wird es ausgeführt und durch Zeile 32 wieder gelöscht.

In Zeile 35 wird eine Funktion aufgerufen, die das aktuelle Datum ermittelt und in das Format YYMMDD überführt. Das Ergebnis der Funktion wird in ERRORLEVEL zurückgegeben.

Die FOR-Schleife in Zeile 41-47 ist die Steuerzentrale des Skripts. Die Datei RemoteDirList wird zeilenweise ausgelesen und der Dateiname extrahiert (der auch Leerzeichen enthalten kann). Enthält der Name Leerzeichen, wird die Funktion ProcessFilename durch Zeile 43 aufgerufen; ohne Leerzeichen erfolgt der Aufruf in Zeile 45. ProcessFilename prüft pro Schleifendurchlauf einen Dateinamen im Verzeichnislisting des Servers, ob er der richtige ist.

ProcessFilename erhält als 1. Parameter den Dateinamen und als 2. Parameter das gewünschte Datum. In Zeile 59 wird erstmal kontrolliert, ob die Datei den erforderlichen Typ hat. Wenn nicht, erfolgt ein Rücksprung in die aufrufende FOR-Schleife mit dem Funktionsergebnis 1 (diese Datei ist nicht die Richtige).

Die FOR-Schleife in Zeile 64-68 extrahiert aus dem Dateinamen das Datum und vergleicht es mit dem gewünschten Wert. Bei Übereinstimmung erfolgt in Zeile 66 ein Rücksprung mit dem Funktionsergebenis 0 (richtige Datei gefunden). Ansonsten wird die Funktion durch Zeile 70 mit dem Funktionsergebnis 1 beendet (diese Datei ist nicht die Richtige).

Der Operator && in den Zeilen 43 und 45 führt dazu, daß die Befehle in der Klammer dahinter nur ausgeführt werden, wenn ProcessFilename eine 0 (Datei gefunden) zurückgegeben hat. Die Operatoren & in der Klammer verketten nur die einzelnen Befehle, alle werden ausgeführt.

Es wird also zunächst mal die Meldung "Gefunden" und ein Zeilenvorschub ausgegeben und dann die Prozedur CopyFile mit dem Dateinamen als Parameter aufgerufen. Wenn CopyFile ausgeführt wurde, wird das Skript durch EXIT /B beendet. Wenn ProcessFilename die gewünschte Datei im Verzeichnislisting des Servers nicht gefunden hat, wird Zeile 49 ausgeführt (Meldung "Nicht gefunden") und das Skript danach beendet.

In der Prozedur CopyFile wird in Zeile 77 geprüft, ob die Datei auf dem lokalen Rechner schon vorhanden ist. Wenn ja wird eine entsprechende Meldung ausgegeben und ein Rücksprung ausgeführt.

Ansonsten wird in den Zeilen 86-91 wieder ein temporäres FTP-Skript erzeugt, das die Befehle zum download der Datei enthält. In Zeile 93 wird es ausgeführt und in Zeile 94 wieder gelöscht.

Die FOR-Schleife in der Funktion GetDate zerlegt das aktuelle Datum in seine Bestandteile (Trennzeichen ist wegen delims=. der Punkt) und setzt es im Format YYYYMMDD wieder zusammen. In Zeile 105 werden die letzten 6 Zeichen extrahiert und in ERRORLEVEL zurückgegeben.

Gruß
Friemler
Mitglied: 60730
60730 20.08.2010 um 23:29:32 Uhr
Goto Top
moin Friemler,

da hast du dir aber "viel" Mühe gegeben face-wink

Leider ist die Syntax vom FTP falsch

Statt:
25. >>"%FTPGetDir%" echo user %Usr% %Pwd%

muß es lauten:
25. >>"%FTPGetDir%" echo %Usr%
26. >>"%FTPGetDir%" echo %Pwd%
bzw: auch in Ihrer Variante zum saugen:
87a,87b
und neue Zeile 88:
88. >>"%FTPGetDir%" echo binary
Das gäbe ansonsten lokal feinsten Datenmüll, wenn er zips ohne diesen Befehl absaugt

Aber wie geschrieben, wenn er Wget benutzen kann, reduziert sich der ganze Kram auf ein minimum und ist deutlich flexibler.
(Wenn im Ordner auch andere zip, die nicht gesaugt werden sollen - natürlich nicht - da müsste man eine zusätzliche findstr /v Zeile einpassen).

Gruß
Mitglied: Friemler
Friemler 20.08.2010 um 23:48:17 Uhr
Goto Top
Hallo Timo,

Zitat von @60730:
Statt:
> 25. >>"%FTPGetDir%" echo user %Usr% %Pwd%

muß es lauten:
> 25. >>"%FTPGetDir%" echo %Usr%
> 26. >>"%FTPGetDir%" echo %Pwd%

also bei mir funktioniert meine Zeile 25 (kann mich so z.B. am AVM-FTP-Server mit User anonymous, Passw. anonymous@example.com anmelden). USER ist ein FTP-Subbefehl, der genau diese Syntax hat. Liegt das vielleicht am Parameter -N bei Aufruf von FTP in Zeile 30 bzw. 92 93? face-wink

und neue Zeile 88:
> 88. >>"%FTPGetDir%" echo binary
Das gäbe ansonsten lokal feinsten Datenmüll, wenn er zips ohne diesen Befehl absaugt

Tja, das ist meine mangelnde Routine mit FTP, hab' ich verschwitzt. Danke für den Hinweis, werde es oben ändern.

Gruß
Friemler