ftplib - Merkwürdiges Problem

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hi Leute,

folgendes Problem:

Ich habe mir das FTP Script aus dem Python Verzeichnis geschnappt (aus Tools -> Scripts -> ftpmirror.py) und habe drum herum einen kleinen Wrapper gebastelt.

Der Wrapper macht nichts anderes, als eine kleine Eingabeaufforderung zu implementieren, in welcher man wählen kann, ob eine von mir erstellte Config-Datei verwendet wird mit den FTP Zugangsdaten oder ob man sich manuell verbinden will. Dazu ein paar try-except Blöcke zur Fehlerbehandlung und abschließend wird noch eine Mail versendet die kurz informiert, ob der FTP Download erfolgreich beendet wurde oder ob der Download abgebrochen wurde.

Ich habe das ganze so gelöst, da ich kein neues FTP Script schreiben wollte und mir das fertige mehr als ausreicht.

Zudem handelt es sich um einen reinen Download der Daten von einem Kunden-FTP-Server, also quasi soll nur per Script automatisch eine Spiegelung erstellt werden, weil es uns zu umständlich war das ganze immer per FTP Programm manuell zu machen.


Als ich das Script getestet habe auf einem unserer eigenen FTP Server lief es fehlerfrei durch, durchsucht alle Verzeichnisse rekursiv, lädt alle Dateien runter und erstellt auch alle Ordner.

Kurzum: Die Spiegelung der Daten funktioniert problemlos.

Heute jedoch habe ich feststellen müssen, dass die Spiegelung vom Kundenserver garnicht klappt. (Also Hinweis: Es handelt sich bei beiden Servern, also Kundenserver und unser eigener Server um Linux Server).

Beim Test des Downloads vom Kunden FTP loggt sich das Script ein, startet im Root-Verzeichnis, erstellt das lokale Download Verzeichnis und:

meldet dass es fertig ist. Ohne einen einzigen Ordner oder eine Datei geladen zu haben.

Auch wird keine Fehlermeldung geschmissen, es passiert einfach garnichts.

Ich bin völlig ratlos und behaupte mal, dass es im FTP Script aus dem standard Python Verzeichnis keinen Fehler gibt, denn auf unserem FTP funktioniert es einwandfrei.

Auch im Wrapper den ich geschrieben habe finde ich keinen Fehler und behaupte ebenfalls, dass es daran nicht liegen wird, denn darin findet keinerlei Programmlogik statt, was das FTP Handling betrifft. Das alles macht das FTP Script aus dem Python Verzeichnis.

Also meine Frage:

Wer hat damit auch schon Erfahrungen gemacht? Dass ein und dasselbe Script auf zwei gleichen Servern einmal problemlos funktioniert und auf dem anderen garnichts lädt obwohl es zu keinen Fehlermeldungen kommt?

Gibt es irgendwelche Besonderheiten die zu beachten sind, was Linux Server betrifft? (Wobei ich nicht weiss, was auf dem Kundenserver anders sein könnte)??

Hier noch mein Konsolenoutput wenn das Script auf dem Kundenserver startet:

Code: Alles auswählen

C:\Users\*****\Desktop\ftp>python ****FTPTransfer.py -f
Connecting to '******'...
Logging in as '*****'...
OK.
Creating local directory 'C:\\Users\\*****\\Desktop\\tempFtpFiles
Listing remote directory '/'...

-- FTP transfers completed --

Confirmation email sent...

C:\Users\*****\Desktop\ftp>

Wenn ich mir den Server per FTP Programm anschaue dann ist die Struktur ebenfalls so wie auf meinem Testserver, also damit ist gemeint dass es sich um normale Verzeichnisse handelt die auch rekursiv abgearbeitet werden sollten.


Kann mir da Jemand helfen?

Ich bin ratlos wo das Problem liegen könnte.


Gruss
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Zur Ergänzung:


Hier meine Settings File aus der ich die FTP Verbindungsdaten Parse:

Code: Alles auswählen

server = *******
username = *****
passwort = *****
rootVerzeichnisAufServer = /
lokalesTempVerzeichnis = C:\Users\******\Desktop\tempFtpFiles

Und hier mein Wrapper um das FTP Script (und bitte schenkt dem Code Style keine Beachtung, es ist ne reine Quick&Dirty Lösung die einfach nur laufen soll):

Code: Alles auswählen

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import ftpmirror
import sys
import pyMail

#ftp settings
server = ""
username = ""
password = ""
rootDirToMirror = ""
localDir = ""

ftpSettings = []

def usage():
	print "\n## Usage: ##\n"
	print ">> python *****FTPTransfer.py [*args*]\n"
	print "[Arguments] =>\n"
	print "-[server] \n-[username] \n-[password] \n-[root directory on server] \n-[local directory name]"
	print "\nOR: [-f] to force using the settings file."
	print "\nAll arguments must be specified or the 'ftpSettings.txt' file is used.\n"

def getFileParams():
	try:
		file = open("ftpSettings.txt", "rb")
		for line in file:
			ftpSettings.append(line)

		server = ftpSettings[0].split("=")[1].strip()
		username = ftpSettings[1].split("=")[1].strip()
		password = ftpSettings[2].split("=")[1].strip()
		rootDirToMirror = ftpSettings[3].split("=")[1].strip()
		localDir = ftpSettings[4].split("=")[1].strip()
		
		return server, username, password, rootDirToMirror, localDir
	except:
		print "Error while processing settings file."
	finally:
		file.close()

	
if len(sys.argv) == 2:
	if sys.argv[1] == "-f":
		server, username, password, rootDirToMirror, localDir = getFileParams()
	else:
		usage()
		sys.exit()
elif len(sys.argv) < 2 or len(sys.argv) > 6:
	usage()
	print "Do you want to use the settings file to connect the FTP server? [yes/no]"
	choice = raw_input("Choice: ")
	if choice in ["y", "ye", "yes", "j", "ja"]:
		print "\n** Using settings file for FTP processing **\n"
		server, username, password, rootDirToMirror, localDir = getFileParams()
	else:
		print "\n** Exiting program. Please restart the program with valid arguments! **\n"
		sys.exit()
else:
	if len(sys.argv) != 6:
		print "\nPlease specify exactly '5' arguments!"
		usage()
		sys.exit()
	try:
		server = sys.argv[1]
		username = sys.argv[2]
		password = sys.argv[3]
		rootDirToMirror = sys.argv[4]
		localDir = sys.argv[5]
	except:
		print "Error evaluating arguments from commandline."

try:
	ftpmirror.main(server, username, password, rootDirToMirror, localDir)
	print "\n-- FTP transfers completed --\n"
	try:
		pyMail.main("success")
		print "Confirmation email sent..."
	except:
		print "Error sending confirmation email."
except:
	print "Error while starting or processing FTP actions."
	pyMail.main("fail")
	print "Error mail sent..."


ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Ok, ich muss mal zurückrudern und das ganze aktualisieren:

Der Kundenserver ist ein WINDOWS 2003 SERVER !

:?

Kann ftplib mit Windows Servern umgehen?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

ne0h hat geschrieben:Kann ftplib mit Windows Servern umgehen?
Welches Betriebssystem auf der Zielmaschine läuft sollte völlig egal sein. Entscheidend ist, dass der FTP-Server korrekt implementiert wurde.

Interessant sind natürlich die Zugriffsberechtigungen. Kannst du dich manuell einloggen und die beschriebenen Aktionen durchführen?
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hi,

also ich bin leider kein FTP Experte, aber:

Wenn ich mit Filezilla durch die Verzeichnisse navigieren will, dann sehe ich im Logfenster oben meine Aktionsmeldungen.

Auf dem funktionierenden Linux Server (also auf welchem ich teste) sehe ich z.B. folgendes wenn ich in ein Verzeichnis navigiere:

Code: Alles auswählen

Status:	Empfange Verzeichnisinhalt...
Befehl:	CWD test2
Antwort:	250 OK. Current directory is /test2
Befehl:	PWD
Antwort:	257 "/test2" is your current location
Befehl:	PASV
Antwort:	227 Entering Passive Mode (80,67,27,51,239,177)
Befehl:	MLSD
Antwort:	150 Accepted data connection
Antwort:	226-ASCII
Antwort:	226-Options: -a -l 
Antwort:	226 5 matches total
Status:	Anzeigen des Verzeichnisinhalts abgeschlossen

Auf dem Windows Server steht folgendes:

Code: Alles auswählen

Status:	Empfange Verzeichnisinhalt...
Befehl:	CWD ******
Antwort:	250 CWD command successful.
Befehl:	PWD
Antwort:	257 "/******/*****" is current directory.
Befehl:	PASV
Antwort:	227 Entering Passive Mode (199,231,148,83,10,194).
Befehl:	LIST
Antwort:	125 Data connection already open; Transfer starting.
Antwort:	226 Transfer complete.
Status:	Anzeigen des Verzeichnisinhalts abgeschlossen

Also kein grosser Unterschied. Das funktioniert scheinbar.

Jedoch sind die Ordner auf dem Windowsserver in meiner Filezilla Ansicht alle mit einem schwarzen Fragezeichen versehen wohingegen die Ordner auf dem Linux Server normal dargestellt werden.

Die Berechtigungen habe ich mal als Screenshot festgehalten.


Das hier sind die Berechtigungen auf dem Linux Server:

Bild


Und das hier sind die auf dem Windowsserver:

Bild


Beides sind Screens aus Filezilla heraus gemacht.



Gruss
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Ach ja, manuell einloggen und Daten per FTP Client runterladen geht problemlos.

Das hier ist das Anweisungslog für einen Download vom Windowsserver:

Code: Alles auswählen

Status:	Auflösen der IP-Adresse für ************
Status:	Verbinde mit **************...
Status:	Verbindung hergestellt, warte auf Willkommensnachricht...
Antwort:	220 Microsoft FTP Service
Befehl:	USER ********
Antwort:	331 Password required for ***********
Befehl:	PASS *******
Antwort:	230 User ******** logged in.
Status:	Verbunden
Status:	Starte Download von /********/*********.pdf
Befehl:	CWD /*******/*******
Antwort:	250 CWD command successful.
Befehl:	PWD
Antwort:	257 "/*********/********" is current directory.
Befehl:	TYPE I
Antwort:	200 Type set to I.
Befehl:	PASV
Antwort:	227 Entering Passive Mode (199,231,148,83,11,246).
Befehl:	RETR **********.pdf
Antwort:	125 Data connection already open; Transfer starting.
Antwort:	226 Transfer complete.
Status:	Dateitransfer erfolgreich
Status:	Verbindung zum Server getrennt


Gruss
Zuletzt geändert von ne0h am Dienstag 5. Januar 2010, 12:02, insgesamt 1-mal geändert.
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

So,

ich habe jetzt nochmal meine ganzen Wrapper weggelassen und ausschliesslich das "ftpmirror.py" Script verwendet, mit folgenden Parametern aufgerufen:

Code: Alles auswählen

C:\Users\*****\Desktop>python ftpmirror.py -l ******* -p ***** host.xy / C:\Users\******\Desktop\xy

Und wieder klappt es einwandfrei auf dem Linuxserver, auf dem Windowsserver kommt wieder nur zurück:

Code: Alles auswählen

Connecting to '************'...
Logging in as '*********'...
OK.
Listing remote directory '/'...
Kein Download, einfach garnichts.... :?:
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hmm...

so langsam komme ich dem Kern näher... (schätze ich)...

Ich habe jetzt versucht, den Download einer Datei (ist ein PDF) manuell Schritt für Schritt im interaktiven Python Modus nachzuvollziehen.

Was dann so aussieht:

Code: Alles auswählen

>>> import ftplib
>>> ftp = ftplib.FTP("*********","********","********")
>>> ftp.cwd("/*********/*********")
'250 CWD command successful.'
>>> fp = open("bla.pdf", "wb")
Bis hierhin ist alles Ok.

Wenn ich nun eine bestimmte Datei im binary mode laden will:

Code: Alles auswählen

>>> ftp.retrbinary("RETR " + " ********.pdf", fp.write, 8 * 1024)
Hagelts mir folgende Exception um die Ohren:

Code: Alles auswählen

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python26\lib\ftplib.py", line 394, in retrbinary
    conn = self.transfercmd(cmd, rest)
  File "C:\Python26\lib\ftplib.py", line 356, in transfercmd
    return self.ntransfercmd(cmd, rest)[0]
  File "C:\Python26\lib\ftplib.py", line 327, in ntransfercmd
    resp = self.sendcmd(cmd)
  File "C:\Python26\lib\ftplib.py", line 243, in sendcmd
    return self.getresp()
  File "C:\Python26\lib\ftplib.py", line 218, in getresp
    raise error_perm, resp
ftplib.error_perm: 550  ******.pdf: The system cannot find the file specified.

Die Datei ist aber nachweislich da !!! Das selbe passiert auch mit anderen Dateien, egal welche ich ausprobiere.

Auch das aktuelle Arbeitsverzeichnis (cwd) ist richtig gesetzt.

Also habe ich gerade versucht, für diese Datei die Berechtigungen anders zu setzen und zwar "Öffentliche Berechtigungen" auf LESEN (alles per FTP Client).

Als Antwort auf den Versuch erhalte ich:

Code: Alles auswählen

Status:	Berechtigungen für '/****/*****/****/***/***.pdf' werden auf '644' gesetzt
Befehl:	SITE CHMOD 644 *****.pdf
Antwort:	500 'SITE CHMOD 644 *****.pdf': command not understood

So, jetzt frage ich mich:

Warum versteht ein FTP Server keinen FTP Befehl zum setzen der Dateirechte??
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Ein

Code: Alles auswählen

>>> ftp.retrlines("LIST")
zeigt mir die Datei klar und deutlich in meinem aktuellen cwd an:

Code: Alles auswählen

06-23-08  03:48PM  241522 *******.pdf
'226 Transfer complete.'
Allerdings sind auch hier keine Dateiberechtigungen zu sehen....
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hat sich dann auch erledigt.

Zur Info: Ein einfaches mit dem Parameter zum rekursiven Aufruf direkt auf dem Linuxserver (wo die Daten hinwandern sollten) bringt die gewünschte Lösung.
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Hat sich ja praktisch erledigt, aber dass du auf dem Kundenserver per FTP-Client keine Berechtigungen stezen darfst, leuchtet eigentlich ein, oder?
ne0h
User
Beiträge: 115
Registriert: Samstag 16. Februar 2008, 11:35

Hat sich ja praktisch erledigt, aber dass du auf dem Kundenserver per FTP-Client keine Berechtigungen stezen darfst, leuchtet eigentlich ein, oder?
Jap, das leuchtet ein. Ich hatte mal wieder den Wald vor lauter Bäumen nicht gesehen.
Antworten