FTP - Wechsel in ein übergeordnetes Verzeichnis

  • Moin,

    seit 3 Tagen sitze ich an dem Problem, dass ich nach erfolgreicher FTP-Verbindung nicht in einer übergeordnetes Verzeichnis wechseln kann. Sprich: befinde ich mich im Verzeichnis /app/Anwendung/FTP-Verzeichnis komme ich nicht nach /var/app/Anwendung/Log-Verzeichnis, um von dort die Log-Files zu ziehen.
    An den Rechten liegt es schonmal nicht. Erstelle ich ein Script und führe dies mit psftp aus, funktioniert das hervorragend. Siehe Code:

    Spoiler anzeigen
    [autoit]

    Func createScriptFile($fileFlag=0)
    local $tempRet
    If FileExists(@ScriptDir & "\getTraceLog.scr") Then
    FileDelete(@ScriptDir & "\getTraceLog.scr")
    EndIf
    If $fileFlag = 1 Then
    $tempRet = FileOpen(@ScriptDir & "\getTraceLog.scr", 1)
    If $tempRet <> -1 Then
    FileWrite($tempRet, 'get "/var/app/Anwendung/trace.log" "' & @ScriptDir & '\trace_new.log"' & @CRLF)
    FileWrite($tempRet, 'quit')
    Endif
    FileClose($tempRet)
    EndIf
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func getTraceLog($Server = "")
    If $Server = "" Then
    $Server = $selectedServer ; $selectedServer wird ggf. an anderer Stelle ermittelt (aus ListBox)
    EndIf
    createScriptFile(1)
    If FileExists($traceFile) Then ; $traceFile ist der Name der Datei
    FileDelete($traceFile)
    EndIf
    $traceServer = $Server
    If $traceServer <> "0" Then
    RunWait('"' & @ComSpec & '" /c ' & "d:\psftp.exe -pw Passwort User -b " & @ScriptDir & "\getTraceLog.scr", @ScriptDir, @SW_HIDE, BitOr($STDERR_CHILD, $STDOUT_CHILD, $STDIN_CHILD))
    EndIf
    createScriptFile()
    EndFunc

    [/autoit]


    Versuche ich das Ganze jetzt mit den gegebenen FTP-Funktionen, lande ich nur im Start-Verzeichnis des FTP-Users. Versuche, mit _FTP_DirSetCurrent das aktuelle Verzeichnis zu wechseln, schlagen fehl bzw. das aktuelle Verzeichnis ändert sich nicht. Hier der aktuelle Code:

    Spoiler anzeigen
    [autoit]


    #include <FTPEx.au3>
    #include <array.au3>
    #include <file.au3>
    Global $traceArray, $aFile, $ftpFileHandle, $string, $h_Handle

    [/autoit] [autoit][/autoit] [autoit]

    $server = 'Server'
    $username = 'User'
    $pass = 'Passwort'

    [/autoit] [autoit][/autoit] [autoit]

    $Open = _FTP_Open('MyFTP Control')
    $Conn = _FTP_Connect($Open, $server, $username, $pass)

    [/autoit] [autoit][/autoit] [autoit]

    If @error Then _Exit()
    _FTP_DirSetCurrent($Conn, "/var/app/Anwendung/")
    MsgBox(0, "", _FTP_DirGetCurrent($Conn)) ;Ergebnis ist und bleibt "/", egal ob ich vorher ein _FTP_DirSetCurrent mache
    $aFile = _Ftp_ListToArray($Conn) ;damit habe ich überprüft, wo ich mich gerade befinde
    _ArrayDisplay($aFile)
    $aFile = _FTP_FileGet($Conn, "//var/app/Anwendung/trace.log", @ScriptDir & "\trace_new.log") ; verzweifelter Versuch trotzdem was zu holen - wurde auch mit nur einem "/" am Anfang versucht
    If @error Then
    MsgBox(0, "", "Es wurde nichts geladen")
    _exit()
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $Ftpc = _FTP_Close($Open)

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc

    [/autoit]


    Mache ich was falsch oder ist das mit den bereitgestellten _FTP-Funktionen nicht möglich? Vielen Dank schonmal an euch.

    Einmal editiert, zuletzt von Grandpa (8. August 2014 um 11:53)

  • Verstehe ich das richtig du willst dir einfach Werte aus Dateien eines Anderen Pfades von deinem Server ziehen? Hast du das ganze schon mal mit Admin-Rechten ausgeführt also mit #RequireAdmin, weil wenn gar nichts passiert, kann das vielleicht damit zusammen hängen. Kannst du dich überhaupt auf den Server schalten oder schlägt selbst das fehl? Und letzte Frage die sich stellt ist das andere Verzeichnis auf dem FTP erstellt?

    • Ja, ich möchte mir Dateien eines anderen Pfades ziehen. Die Logdateien liegen im Verzeichnis der Anwendung selbst, nicht im Datenverzeichnis. Der FTP_User landet aber nach dem Verbinden automatisch im Datenverzeichnis. Das ist das Problem.
    • Als Admin kann ich das Ganze nicht ausführen, da der Server nicht mir "gehört". Mir gehören die Daten der Anwendung. Allerdings muss ich ich ab und zu die Logs auswerten. Und die liegen nunmal im Verzeichnis der Anwendung.
    • Ja. Der Zugriff funktioniert ohne weiteres, da ich ja wie gesagt per psftp und automatisch erstelltem Script die Dateien ziehen kann. Per Putty komme ich auch ohne Probleme auf den Server und kann in den Verzeichnissen rumspringen und mir die Dateien anschauen. Wie gesagt - an den Rechten (Dateien: -rw-r--r-- , Verzeichnis: drwxr-xr-x) liegt es nicht.
    • And last but not least - ja, das/die Verzeichnis/se existiert/existieren.

    Wie schon geschrieben. Ich habe das Gefühl, dass ich mit _ftp_dirsetcurrent maximal weitere Ebenen runter aber nicht hoch komme. Sprich, aus /app/Anwendung/ komme ich nicht heraus.

    Aber gleich ne Frage nebenbei: macht es überhaupt einen Unterschied (zeitlich gesehen) mit den AutoIt-Funktionen den Dateitransfer durchzuführen? Oder nimmt sich das nichts? Wir reden hier von einer Gesamtgröße von ca 25 bis 26 Mb.

  • Ich sehe bei dir keine Fehlerbehandlung.
    Ohne dieses können wir uns auch mit einer Glaskugel auf dem Jahrmarkt treffen.
    Füge daher folgendes direkt hinter dein _FTP_DirSetCurrent ein und sage ob eine Ausgabe kommt und wenn ja - was steht dort geschrieben?

    [autoit]

    If @error Then
    Local $err=@error, $ext=@extended, $dError, $sMessage
    MsgBox(48, "Fehler", "Return: " & $dRet & @CRLF & "@Error: " & $err & @CRLF & "@extended: " & $ext )
    If $ext = 12003 Then
    _FTP_GetLastResponseInfo($dError, $sMessage)
    MsgBox(0,"_FTP_GetLastResponseInfo", "dError: " & $dError & @CRLF & "Message: " & $sMessage)
    EndIf
    EndIf

    [/autoit]
  • Entschuldige, dass ich die Fehlerbehandlung dort weggelassen hatte. Ich mache eigentlich immer eine Fehlerbehandlung. Deswegen sind "3-Zeiler" bei mir dann 5 oder 6 Zeilen lang. :D Ich hab jetzt mal deine Zeilen eingefügt und durfte feststellen, dass das Script bzw. der Befehl _FTP_DirSetCurrent($Conn, "/") oder _FTP_DirSetCurrent($Conn, "//") die Variable @error nicht mit einem Wert belegt. @error hat den Wert 0 (hab ich mir ausgeben lassen). Obwohl kein Fehler besteht, habe ich den Befehl _FTP_GetLastResponseInfo($dError, $sMessage) ausgeführt und mit dem Befehl MsgBox(0, "", "Error: " & @error & @CRLF & "Return: " & $dRet & @CRLF & $dError & " - " & $sMessage) folgendes zurück bekommen:

    Error: 0
    Return: 1
    0 - 250 CWD command succesful

    Bedeutet ja eigentlich, dass der Befehl ohne Fehler mit Rückgabewert 1 durchgeführt wurde. Der Wert von @error kommt quasi doppelt drin vor.
    Einen Fehler in diesem Sektor kann man also schonmal ausschließen. Das bestätigt aber gleichzeitig meinen Verdacht, dass ich auf diese Weise nicht aus dem Verzeichnis heraus komme. Für diese FTP-Session stecke "logisch" ich im root, auch wenn es real nicht der Fall ist. Sprich eine Etage höher geht nicht. Irgendwie deprimierend.

  • Das sieht ja wirklich merkwürdig aus.
    Wenn es ein Bug ist müssen wir uns mal schrittweise vortasten wo denn der Bug genau liegt.
    Damit wir auch die Selbe Codebasis haben verwenden wir zum Testen nun nur noch folgenden Code:

    Testcode für FTP-Bug
    [autoit]

    #include <FTPEx.au3>
    #include <array.au3>
    Global $h_WinInet_DLL = DllOpen("Wininet.dll")

    [/autoit] [autoit][/autoit] [autoit]

    Global $server = 'Server'
    Global $username = 'User'
    Global $pass = 'Passwort'
    Global $directory = "/var/app/Anwendung/"

    [/autoit] [autoit][/autoit] [autoit]

    $Open = _FTP_Open('MyFTP Control')
    $Conn = _FTP_Connect($Open, $server, $username, $pass)
    ;~ $dRet = _FTP_DirSetCurrent($Conn, $directory)
    $a_Ret = DllCall($h_WinInet_DLL, 'bool', 'FtpSetCurrentDirectory', 'handle', $Conn, 'str', $directory)
    GetAllFTPErrors($a_Ret[0] & " - " & $a_Ret[2])

    [/autoit] [autoit][/autoit] [autoit]

    $a_Ret = DllCall($h_WinInet_DLL, 'bool', 'FtpGetCurrentDirectory', 'handle', $Conn, 'str', "", 'DWORD*', 260)
    GetAllFTPErrors($a_Ret[0] & " - " & $a_Ret[2])

    [/autoit] [autoit][/autoit] [autoit]

    _FTP_Close($Conn)
    _FTP_Close($Open)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func GetAllFTPErrors(Const $ReturnValue = "", Const $err = @error, Const $ext = @extended)
    Local $dFTPError, $sFTPMessage, $dAPIError = _WinAPI_GetLastError(), $dAPIMessage = _WinAPI_GetLastErrorMessage()
    _FTP_GetLastResponseInfo($dFTPError, $sFTPMessage)
    MsgBox(0, "Error-Report", ($ReturnValue ? "Return: " & $ReturnValue & @CRLF : "") & "@error: " & $err & @CRLF & "@extended: " & $ext & @CRLF & "API-Error: " & $dAPIError & " - " & $dAPIMessage & @CRLF & "FTP-Error: " & $dFTPError & " - " & $sFTPMessage)
    EndFunc ;==>GetAllFTPErrors

    [/autoit]


    Passe hier da bitte noch deinen Server, Name und Passwort an und lasse alles andere unangetastet.
    Dann bitte ausführen und die Ergebnisse posten.
    (habe u.A. direkt die DLL-Calls genommen und dabei auf die ASCII-Funktionen zurückgegangen).

    Btw: Wenn dein Nutzername mit deinem Profilbild übereinstimmen sollte müsstest du "Grampa" heißen... ;)

  • Sorry, dass ich erst jetzt antworte. War etwas busy. Ich habe jetzt mal deinen Code genommen, entsprechend angepasst und ausgeführt. Die erste Ausgabe sah folgendermaßen aus:
    [Blockierte Grafik: https://lh4.googleusercontent.com/Ygft-WdMU1w8j2HzAEtk_vWFBQYZw8IgxJjqjh_YvBg=w404-h207-p-no]
    Interpretieren muss man da ja nicht viel. Er kann das Verzeichnis nicht finden. Klar, denn der Inhalt des Verzeichnisses, in dem er sich aktuell befindet sieht folgendermaßen aus (ein Ausschnitt):
    [Blockierte Grafik: https://lh3.googleusercontent.com/V5_XkRExDUHpHDMzLV6DcL3LRgJ30UqNxrZzk7761yY=s192-p-no]
    Das sind 100 Verzeichnisse (00-99) und noch 2 Dateien. Und das Verzeichnis, in dem er sich gerade befindet, ist folgendes: /app/mt2/ftp/efn>

    Und jetzt noch die zweite deiner Ausgaben:
    [Blockierte Grafik: https://lh6.googleusercontent.com/4T4CPjBfZZonI8xBxiNJXovh7fvZ4VF7Kqm3q5ZbYOU=w319-h207-p-no]

    Als Endergebnis kann man also sagen, dass das von mir gepostete Verzeichnis (/app/mt2/ftp/efn/) nicht so erkannt wird, sondern als '/' gewertet wird.

    Und jetzt kommst du. ;)

    PS: Jetzt kennst du die eigentliche Verzeichnisstruktur. Ich habe ursprünglich andere Namen gewählt, da es sich um einen Firmenserver handelt. Aber das spielt ja keine Rolle bei dem eigentlichen Problem.

    PPS: Warum sollte ich Grampa heißen. Verstehe grad den Witz dahinter nicht. Simpson Grandpa heißt doch Abe?

    Einmal editiert, zuletzt von Grandpa (7. August 2014 um 11:34)

  • Bist du sicher, dass du das Skript bis auf die Variablen $server, $username, $pass und $directory unangetastet gelassen hast?
    Weil in der Messagebox sollte als erstes "Return: " stehen.
    Bei dir steht aber schon der Inhalt des Rückgabewertes.

    Nun habe ich doch noch ein paar Fragen:

    Er kann das Verzeichnis nicht finden. Klar, denn der Inhalt des Verzeichnisses, in dem er sich aktuell befindet sieht folgendermaßen aus (ein Ausschnitt):

    Das verstehe ich nicht warum das klar sein soll - was hat dies mit dem aktuellen Ordner zu tun?
    Die Fehlemeldung sagt für mich aus: Auf dem verbundenen FTP-Server gibt es keinen Ordner namens /var/app/mt2inet/log/tomcat-7.0.27-inst1/
    Du willst in den Ordner /var/app/mt2inet/log/tomcat-7.0.27-inst1/ wechseln?
    Warum befindest du dich zu diesem Zeitpunkt schon in, laut deiner Aussage, /app/mt2/ftp/efn/?
    Im Testkript gibt es doch nur ein FtpSetCurrentDirectory?
    Du solltest dich also im Ursprungszustand im Root-Verzeichnis befinden.

    Jetzt kennst du die eigentliche Verzeichnisstruktur.

    So wirklich nicht - du redest auf einmal von zwei verschiedenen Verzeichnissen obwohl wir ein FtpSetCurrentDirectory auf nur ein bestimmtes testen wollten.
    Ist /var/app/mt2inet/log/tomcat-7.0.27-inst1/ nur ein Unterordner von /app/mt2/ftp/efn/?
    Pfadangaben bei FtpSetCurrentDirectory sind immer vom Wurzelverzeichnis aus gemeint - nicht als Unterordner eines aktuellen Verzeichnisses.

    PPS: Warum sollte ich Grampa heißen. Verstehe grad den Witz dahinter nicht. Simpson Grandpa heißt doch Abe?

    Grampa bei den Simpsons wird nicht Grandpa sondern Grampa geschrieben.

  • so gehts...


    Spoiler anzeigen
    [autoit]

    #include <FTPEx.au3>
    #include <array.au3>
    #include <file.au3>
    Global $traceArray, $aFile, $ftpFileHandle, $string, $h_Handle

    [/autoit] [autoit][/autoit] [autoit]

    $server = 'ftp.microsoft.com'
    $username = ''
    $pass = ''

    [/autoit] [autoit][/autoit] [autoit]

    $Open = _FTP_Open('MyFTP Control')
    $Conn = _FTP_Connect($Open, $server, $username, $pass,0) ;flag...
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Conn = ' & $Conn & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    If $conn=0 Then Exit(msgbox(0,0,"bitte nochmal starten!"))

    [/autoit] [autoit][/autoit] [autoit]

    $aFile = _Ftp_ListToArray($Conn) ;damit habe ich überprüft, wo ich mich gerade befinde
    _ArrayDisplay($aFile)

    [/autoit] [autoit][/autoit] [autoit]

    $a=_FTP_DirSetCurrent($Conn, "/PSS/Tools/")
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $a= = ' & $a & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $aFile = _Ftp_ListToArray($Conn) ;damit habe ich überprüft, wo ich mich gerade befinde
    _ArrayDisplay($aFile)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $b=_FTP_DirSetCurrent($Conn, "/") ;root
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $b = ' & $b & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $aFile = _Ftp_ListToArray($Conn) ;damit habe ich überprüft, wo ich mich gerade befinde
    _ArrayDisplay($aFile)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $c=_FTP_DirSetCurrent($Conn, "/Services/enterprise/")
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $c = ' & $c & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $aFile = _Ftp_ListToArray($Conn) ;damit habe ich überprüft, wo ich mich gerade befinde
    _ArrayDisplay($aFile)

    [/autoit] [autoit][/autoit] [autoit]

    exit

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _FTP_DirSetCurrent($Conn, "/var/app/Anwendung/")
    MsgBox(0, "", _FTP_DirGetCurrent($Conn)) ;Ergebnis ist und bleibt "/", egal ob ich vorher ein _FTP_DirSetCurrent mache
    $aFile = _Ftp_ListToArray($Conn) ;damit habe ich überprüft, wo ich mich gerade befinde
    _ArrayDisplay($aFile)
    $aFile = _FTP_FileGet($Conn, "//var/app/Anwendung/trace.log", @ScriptDir & "\trace_new.log") ; verzweifelter Versuch trotzdem was zu holen - wurde auch mit nur einem "/" am Anfang versucht
    If @error Then
    MsgBox(0, "", "Es wurde nichts geladen")
    _exit()
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $Ftpc = _FTP_Close($Open)

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc

    [/autoit]

    der MS server antwortet manchmal nicht, daher Script ggf. öfter starten!

  • Bist du sicher, dass du das Skript bis auf die Variablen $server, $username, $pass und $directory unangetastet gelassen hast?
    Weil in der Messagebox sollte als erstes "Return: " stehen.
    Bei dir steht aber schon der Inhalt des Rückgabewertes.


    Ich hebe dein Script, bis auf Umgebungsrelevante Werte, nicht verändert. Und "Return:" kommt in der MsgBox nicht als erstes. Deine Zeile:

    [autoit]

    MsgBox(0, "Error-Report", ($ReturnValue & "Return: " & $ReturnValue & @CRLF & "") & "@error: " & $err & @CRLF & "@extended: " & $ext & @CRLF & "API-Error: " & $dAPIError & " - " & $dAPIMessage & @CRLF & "FTP-Error: " & $dFTPError & " - " & $sFTPMessage)

    [/autoit]

    Ist aber auch nicht so wichtig.

    Das verstehe ich nicht warum das klar sein soll - was hat dies mit dem aktuellen Ordner zu tun?


    Verstehe ich, dass du das nicht verstehst. Der zweite Screener (_Arraydisplay) zeigt den Inhalt des aktuellen Verzeichnisses (die 99 Ordner und 2 Dateien). Die gibt es aber nur in dem Verzeichnis /app/mt2/ftp/efn/. Warum ich bereits in dem Verzeichnis bin? Nunja. Wenn man auf einem Rechner/Server einen FTP-User einrichtet, dann gibt man ihm i.d.R. einen Pfad, in dem er landen soll, sobald er sich verbunden hat. Und das ist in diesem Fall /app/mt2/ftp/efn/. Mit anderen Usern lande ich woanders. Das sagt aber noch nichts darüber aus, wo ich überall hin darf.
    Das eine _FTP_DirSetCurrent soll mich aber in ein anderes Verzeichnis, welches sich außerhalb des aktuellen Ordners befindet, "verfrachten".

    Ist /var/app/mt2inet/log/tomcat-7.0.27-inst1/ nur ein Unterordner von /app/mt2/ftp/efn/?


    Nein ist es nicht. Genau da liegt anscheinend das Problem. Wie ich schon schrieb, schafft es _FTP_DirSetCurrent scheinbar nicht aus diesem Einsprungsordner (/app/mt2/ftp/efn/) heraus zu gehen und in einen außerhalb liegenden Ordner zu wechseln.
    Hier mal ein Teil der Ordner-Struktur von root. Die Ordner, die für mich bzw. im Script eine Rolle spielen, wurden gleich komplettiert,fett blau markiert und kommentiert.


    drwxr-xr-x 8 root root 1024 Apr 25 10:18 app/mt2/ftp/efn/ ;Einsprungsordner nach FTP-Login
    drwxr-xr-x 2 root root 4096 Jun 4 19:06 bin
    drwxr-xr-x 4 root root 1024 Jun 4 19:11 boot
    .
    .
    drwxr-xr-x 14 root root 4096 Feb 15 2012 usr
    dr-xr-xr-x 18 root root 4096 Jun 4 19:07 var/app/mt2inet/log/tomcat-7.0.27-inst1/ ;Ordner, wo ich hin will

    Man sieht, ich muss ins root und dann in den Zielordner. Oder wenn ich auf der Konsole wäre, mit diesem Befehl direkt wechseln:


    Server:/app/mt2/ftp/efn> ;Einsprungsordner - wird von _FTP_DirGetCurrent als '/' erkannt
    Server:/app/mt2/ftp/efn> cd /var/app/mt2inet/log/tomcat-7.0.27-inst1 ;Befehl - _FTP_DirSetCurrent sollte eigentlich das gleiche wie cd machen
    Server:/var/app/mt2inet/log/tomcat-7.0.27-inst1> ;gewünschtes Ergebnis

    Ich hoffe damit ist jetzt etwas Licht ins Dunkel gekommen.

    Einmal editiert, zuletzt von Grandpa (8. August 2014 um 10:15)

  • Nachtrag: Danke für eure Unterstützung. Aber am Ende ist die "Lösung" bzw. Erkenntnis wahrscheinlich sehr simpel. Wenn die Option DefaultRoot auf das Verzeichnis gesetzt ist, dann kann ich mit FTP machen was ich will. Ich komme in kein übergeordnetes Verzeichnis. Somit kann ich mir jegliche weitere Mühe sparen und muss Wohl oder Übel auf meine Script-Version zurück greifen.

    Danke trotzdem nochmal euch allen. :rock: