PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Vista-Bordmittel-FTP-Upload


Firefall
06.05.2008, 17:40
So jetzt hätte ich ausnahmsweise mal gerne ein Shellscript aber weiss nicht wie schreiben :) Ich möchte eine leere Datei mit frei wählbarem Namen automatisch auf einen FTP hochladen. Idealerweise möchte ich in der Batch einfach den Namen eingeben und dann sollte das laufen. Ansonsten ein Drag & Drop Upload. Zielpfad, User & PW sind bekannt. Krieg ich das hin, aus einer Batch? In "DOS" gibt's ja das FTP-Progamm... Kann ich damit arbeiten?


Schorsch
07.05.2008, 00:26
Du könntest dir einen *.ftp Datei erstellen mit zb. folgendem Inhalt:


OPEN ftp.server.de
USER user
passwort
binary
put c:\datei.txt ./datei.txt
BYE


Diese Datei kann du dann mit ftp -s dateiname.ftp ausführen.

Wenn du die Datei dann mit noch dynamisch erzeugst und einen übergeben Parameter dort als Dateinamen schreibst, sollte dein Upload funktionieren

Gruß

Schorsch

Firefall
07.05.2008, 11:33
Danke, das hilft mir weiter! Werde demnächst das Script coden und dann den "Source" hier posten! ThX für den Hinweis!

Firefall
07.05.2008, 17:05
Ok, Script geschrieben ;) Bitte sehr:
@echo off
set /p DownloadCode=Enter desired filename:
echo Downloadcodefile >%DownloadCode%
echo OPEN ftp.microsoft.com >>Upload.ftp
echo Billy >>Upload.ftp
echo M$ >>Upload.ftp
echo CD "OS/Vista/" >>Upload.ftp
echo BINARY >>Upload.ftp
echo put %DownloadCode% >>Upload.ftp
echo bye >>Upload.ftp
ftp -s:Upload.ftp
del /q %DownloadCode% Upload.ftp
echo "Upload complete! Press any key to finish."
pause
Getestet und funktioniert bei mir (Mit anderen Angaben für den FTP ;)). Kann mir noch jemand sagen, wie ich ne Datei erzeuge, ohne was reinschreiben zu müssen? Mit echo >neu.txt krieg ich ja "Echo is angeschaltet", respektive aus.
Und dann noch was: Kann ich damit auch irgendwie ne ganze Ordnerstruktur mit Dateien hochladen? Dachte daran, dir mit /b /s und /a:d zu pipen, dann müsste ich aber noch mds davor kriegen bei der Ausgabe und ausserdem die Pfade relativ zum Root hinkriegen... Ist das möglich? Oder überfordere ich da cmd?
Ansonsten nochmals Danke für deine Hilfe Schorsch!

Firefall
07.05.2008, 19:33
Habe einen ersten Ansatz für die Ordnerstruktur:
@echo off
for /f "tokens=2 delims=%cd%" %%d in ('dir /A:D /B /S') do (
echo %%d
)Sollte die Ordnerpfade relativ vom Stammverzeichnis ausgeben. Da kommt aber nur Müll raus. Wie kann ich den blöden Stammverzeichnisspfad abschneiden?!?

Jidder
07.05.2008, 20:26
Mit echo. (echo gefolgt von einem Punkt) kannst du praktisch "nichts" ausgeben. echo.>neuneu.txt erzeugt allerdings eine Datei, die nur einen Zeilenumbruch enthält. Wenn dich dieser stört, könntest du cd.>neuneu.txt nehmen, da cd. ja nix tut und auch nix ausgibt. Ist allerdings nicht mehr so die feine Art ;)

Wie man den Pfad elegant abschneidet weiß ich nicht. Ich würd das mit einer sich rekursiv aufrufenden Batch-Datei machen. Guck dir einfach mal die Ausgabe an, ob es das ist, was du brauchst.

@ECHO OFF

IF {%1}=={} SET DIRECTORY=
IF NOT {%1}=={} SET DIRECTORY=%1\

FOR /D %%I IN (%DIRECTORY%*) DO @(
ECHO MD %%~nxI
ECHO CD %%~nxI
CMD /C UPLOAD.CMD "%%~I"
ECHO CD ..
)

FOR %%I IN (%DIRECTORY%*) DO @(
ECHO PUT %%~fI
)

%DIRECTORY% wird so gesetzt, dass es das aktuell zu bearbeitende Verzeichnis enthält. Wenn die Batch-Datei rekursiv aufgerufen wird, dann wird dieses Verzeichnis in %1 übergeben.
In der ersten FOR-Schleife werden dann alle Unterverzeichnisse durchlaufen, und Pseudo-FTP-Befehle (musst du vermutlich anpassen) zur Erstellung der Verzeichnisse ausgegeben. Für jedes Verzeichnis wird dann die Datei rekursiv aufgerufen und das Unterverzeichnis als Parameter übergeben.

Nachdem die Unterverzeichnisse erstellt wurden, werden in der zweiten FOR-Schleife die Dateien durchlaufen und ein PUT-Befehl mit dem absoluten Pfad ausgegeben.

Am Besten rufst du das mit upload.cmd >>Upload.ftp auf. Dann sparste dir die vielen >>Upload.ftp in der Batch-Datei.

Firefall
07.05.2008, 21:19
Danke für deine Antwort! Für die leere Datei habe ich eine ähnliche Lösung gefunden, type nul >neu.txt. Klappt ganz gut soweit ;) Dachte zuerst noch an cls >neu.txt aber das schreibt komischerweise ein Weiblich-Zeichen oder sowas rein. Ist wohl der Rückgabewert von cls...

Das mit der Rekursion habe ich mir auch überlegt, aber kam dann immer auf 2 Dateien und das wollte ich vermeiden. Die Sache mit dem Parametercheck ist natürlich fein ;) Werde das gleich mal kopieren und schauen ob ich es verstehe, habe drum heute zum ersten Mal mit for und if (in Batch natürlich :D) gearbeitet. Das Prinzip ist mir klar ;) Kann ich deinen Aufruf mit cmd auch durch ein simples call Upload.bat ersetzen? Nehme an schon oder? Danke für die Hilfe! Ich melde mich wieder!
Ps: Zum Aufruf: Das ist leider nicht möglich, ich will nacher per Drag & Drop einen Ordner auf die Batch werfen und mich um nix mehr kümmern müssen ;) Ist aber nett, dass du mich darauf aufmerksam gemacht hast. Hat mich auf die Idee gebracht, den Namen der Datei in einer Variable zu definieren ;)

Firefall
07.05.2008, 21:43
--BITTE LETZTES EDIT LESEN; DER REST IST IRRELEVANT--
Das Resultat:
****** B A T C H R E K U R S I O N überschreitet Stapellimit ******
Rekursionszähler=344, Stapelauslastung=90 Prozent
****** B A T C H V E R A R B E I T U N G A B G E B R O C H E N ******:D Steht echt so da...
EDIT: Ich hatte directory direkt mit %1 ersetzt. Mit deiner directory-Konstruktion geht's. Warum ist das so? Mir fehlt irgendwie gerade der Durchblick :S Liegt das daran, dass die Parameter quasi laufen ersetzt werden und die "alten" dabei aufbewaht werden müssen? Rekursionszähler = 344 irritiert mich auch... Dann müsste ich ja 344 ineinander verschachtelte Ordner haben...
EDIT2: Es funktioniert doch nicht! Irgendwo muss da noch ein Problem mit der Rekursion drin sein, für die ersten Ordner sieht soweit alles korrekt aus aber die letzten sind doppelt drin (Auch die Dateien). Wenn ich das Script aus einer Ebene höher aufrufe sind die entsprechenden Ordner dreifach drin... Hier mein Code, entspricht deinem ziemlich genau:
@echo off

if (%1)==() set DIRECTORY=
if NOT (%1)==() set DIRECTORY=%1\

for /D %%i in (%DIRECTORY%*) do @(
echo md %%~nxi >>lol.txt
echo cd %%~nxi >>lol.txt
call 12.cmd "%%~i"
echo cd .. >>lol.txt
)

for %%i in (%DIRECTORY%*) do @(
echo put %%~fi >>lol.txt
)EDIT3: Es lag an meinem Call. Ich kann nicht mit 100%iger Sicherheit sagen, was das Problem ist, aber nehme stark an, dass es daran liegt, dass beim Call Directory halt eine Art globale Variable ist, weshalb bei dem Dateidurchlauf der Ordner nicht mehr stimmt... Beim Aufruf mit cmd hingegen hat jede Rekursionsstufe ihre eigene Varable Directory. Werde jetzt noch probieren, den VOR den Ordnerdurchlauf zu schmeissen. Möchte den Selbstaufruf von cmd umgehen.
EDIT 4: Klappt. Code soweit:
@echo off

rem if (%1)==() set DIRECTORY=
rem if NOT (%1)==() set DIRECTORY=%1\

set DIRECTORY=%1\

for %%i in (%DIRECTORY%*) do @(
echo put %%~fi >>lol.txt
)

for /D %%i in (%DIRECTORY%*) do @(
echo md %%~nxi >>lol.txt
echo cd %%~nxi >>lol.txt
call 12.cmd "%%~i"
echo cd .. >>lol.txt
)
Jetzt müsste ich noch folgendes wissen:
1. Wie du sehen kannst, habe ich deine Ifs auskommentiert und mein eigenes Statement verwendet. Scheint auch zu funktionieren. Ist mehr oder weniger dasselbe oder?
2. Was fehlt sind noch 2 Dinge: Vor dem ganzen Code in der Ausgabedatei müsste noch der Login kommen und der Rootfolder selbst erstellt werden, also quasi nur ein md/cd %~nx1 wenn ich die Syntax davon richtig verstanden habe. Am Ende schliesslich müsste das Script die .ftp Datei oder was es dann wird korrekt aufrufen, damit der Upload geschieht, und sie anschliessend löschen. Wie kriege ich das hin? Zweiten Parameter "RecursionInProgress" einführen, der beim Rekursionsaufruf angehängt wird und dann vor und nach dem Rekursionscode auf Existenz checken und wen nicht vorhanden Intro/Outro-Code ausführen? Erscheint mir etwas "dreckig" aber ist die einzige Möglichkeit so wie ich das sehe...

Jidder
08.05.2008, 16:18
Die Meldung sieht ja echt mal cool aus ;)

Jo, %DIRECTORY% könnte wirklich global sein. Du könntest dir mal SETLOCAL und ENDLOCAL angucken. Die sorgen dafür, dass sich Änderungen an Variablen nur innerhalb des damit eingegrenzten Bereichs auswirken. Ich habs allerdings nie benutzt. Wenn die Umordnung der Schleifen keine anderen Nebeneffekte mit sich bringt, ist das natürlich die einfachere Lösung.

1. Wie du sehen kannst, habe ich deine Ifs auskommentiert und mein eigenes Statement verwendet. Scheint auch zu funktionieren. Ist mehr oder weniger dasselbe oder?
Wenn du der Datei per Drag & Drop das Ausgangsverzeichnis übergibst, ja. Sonst lädt dir das Ding das gesamte Laufwerk hoch. (In %1 steht dann ja nichts und %DIRECTORY% enthält dann einfach ein "\".)

2. Was fehlt sind noch 2 Dinge: Vor dem ganzen Code in der Ausgabedatei müsste noch der Login kommen und der Rootfolder selbst erstellt werden, also quasi nur ein md/cd %~nx1 wenn ich die Syntax davon richtig verstanden habe. Am Ende schliesslich müsste das Script die .ftp Datei oder was es dann wird korrekt aufrufen, damit der Upload geschieht, und sie anschliessend löschen. Wie kriege ich das hin? Zweiten Parameter "RecursionInProgress" einführen, der beim Rekursionsaufruf angehängt wird und dann vor und nach dem Rekursionscode auf Existenz checken und wen nicht vorhanden Intro/Outro-Code ausführen? Erscheint mir etwas "dreckig" aber ist die einzige Möglichkeit so wie ich das sehe...
Die einzige andere Möglichkeit, die mir einfällt, ist eine globale Variable. Dann gibt es allerdings das Problem, dass die bereits mit einem Wert (z.B. aus einem vorherigen abgebrochenen Lauf deiner Batch-Datei) belegt sein könnte. Sollte aber glaube ich nicht passieren können, wenn du die Datei per Drag & Drop aufrufst, da dann ein frischer cmd-Prozess erstellt wird.

Firefall
08.05.2008, 16:34
Die Meldung sieht ja echt mal cool aus ;)

Jo, %DIRECTORY% könnte wirklich global sein. Du könntest dir mal SETLOCAL und ENDLOCAL angucken. Die sorgen dafür, dass sich Änderungen an Variablen nur innerhalb des damit eingegrenzten Bereichs auswirken. Ich habs allerdings nie benutzt. Wenn die Umordnung der Schleifen keine anderen Nebeneffekte mit sich bringt, ist das natürlich die einfachere Lösung.
Scheint sie nicht, weshalb auch immer... Dachte auch an SETLOCAL, das hat aber nicht so funktioniert, wie ich mir gedacht habe... Hab einfach aus dem Set ein Setlocal gemacht aber das funktioniert nicht. Aus der Hilfe bin ich nicht schlau geworden.
Wenn du der Datei per Drag & Drop das Ausgangsverzeichnis übergibst, ja. Sonst lädt dir das Ding das gesamte Laufwerk hoch. (In %1 steht dann ja nichts und %DIRECTORY% enthält dann einfach ein "\".)Das Script nimmt dann den Ordner, in dem sich die Batch befindet, nicht das Laufwerk ;)
Die einzige andere Möglichkeit, die mir einfällt, ist eine globale Variable. Dann gibt es allerdings das Problem, dass die bereits mit einem Wert (z.B. aus einem vorherigen abgebrochenen Lauf deiner Batch-Datei) belegt sein könnte. Sollte aber glaube ich nicht passieren können, wenn du die Datei per Drag & Drop aufrufst, da dann ein frischer cmd-Prozess erstellt wird.Und wie würdest du das ansetzen? Intro kann ich mir noch einigermassen vorstellen, aber Outro?!
EDIT: Hatte gerade noch eine Idee für die Rekursion. Könnte man nicht mit pushd und popd quasi als Variablenübergeber arbeiten und dann mit GOTO eine Art function implementieren? Habe gerade festgestellt, dass die einen FIFO-Stapel erzeugen... Weiss natürlich nicht, wie lang der dann ist...
EDIT2: Soeben getestet. Schafft 704 Rekursionen:
pushd .
call 1.cmd

Jidder
08.05.2008, 23:45
SETLOCAL funktioniert so:
@ECHO OFF
SET FOO=ALTER WERT
ECHO FOO = %FOO%
SETLOCAL
SET FOO=NEUER WERT
ECHO FOO = %FOO%
ENDLOCAL
ECHO FOO = %FOO%
(Je mehr Großbuchstaben man in Batch-Dateien verwendet, desto cooler ^^)

Am Anfang wird FOO auf den Wert "ALTER WERT" gesetzt und zum Beweis ausgegeben. Das SETLOCAL erstellt dann einen neuen Gültigkeitsbereich und die Variable %FOO% wird auf den Wert "NEUER WERT" gesetzt. Die folgende Ausgabe ist wie zu erwarten FOO = NEUER WERT. ENDLOCAL schließt den Gültigkeitsbereich wieder. %FOO% hat dann wieder seinen vorherigen Wert, und im folgenden wird tatsächlich FOO = ALTER WERT ausgegeben.

Statt %FOO% auf einen Wert zu setzen, würdest du dann die Batch-Datei rekursiv aufrufen, welche das für dich tut.


Mit globaler Variable müsstest du die Rekursion so machen:
@ECHO OFF

IF NOT {%REKURSION%}=={1} (
SET REKURSION=1
ECHO INTRO
CALL "%~0" "%~1"
ECHO OUTRO
SET REKURSION=
GOTO :EOF
)

ECHO DER REST

Ohne die Extrarekursion (CALL "%~0" "%~1") fällt mir auf die Schnelle auch keine andere Möglichkeit für das Outro ein. SET REKURSION= ist bei mir nötig gewesen, wegen dem oben genannten Problem, dass REKURSION sonst auf 1 gesetzt bleibt. (Ich teste das immer in der selben cmd-Umgebungen. Wie gesagt, bei Drag & Drop fällt das weg). GOTO :EOF ist nötig, damit ECHO DER REST nicht nach der Ausgabe von OUTRO ausgeführt wird. Das Ausgangsverzeichnis wird im ersten Rekursionsschritt verarbeitet.

PUSHD und POPD hab ich nie verwendet. Könnte natürlich auch eine Möglichkeit sein.