Datei - letzten Zugriff "loggen"

  • Hallo,
    wir haben hier einige Linuxserver mit Userdaten stehen, die über Samba auf den einzelnen Maschinen den nutzern zur Verfügung gestellt werden. Da sich viel Müll angesammelt hat, möchten wir nun lange nicht mehr aufgerufenen Dateien, löschen. Zuerst dachte ich ja an folgendes, jedenfals nach dem Prinzip:

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <WinAPI.au3>
    #include <Date.au3>
    #include <WindowsConstants.au3>

    ; Liest die Dateizeit
    $hFile = _WinAPI_CreateFile(@ScriptDir & "\Neu AutoIt v3 Script.au3", 2)
    If $hFile = 0 Then _WinAPI_ShowError("Die Datei konnte nicht geöffnet werden")
    $aTime = _Date_Time_GetFileTime($hFile)
    _WinAPI_CloseHandle($hFile)
    MsgBox(1, "lala", _Date_Time_FileTimeToStr($aTime[1]))

    [/autoit]


    Nun haben wir aber bei uns das Problem, dass sämtliche Dateien auf dem Server in irgendeiner Art und Weise von dem System "angefasst" werden, und letzter Zugriffszeitpunkt vorheriger Tag war. Kommt evt. durch eine tägiche Datensicherung. Nun frage ich mich ob es eine Möglichkeit gibt, den Aufruf einer Datei irgendwie zu protokollieren. So könnte man dann in 3 Monaten das Protokoll auswerten, und Dateien die darin nicht vorkommen, löschen. Ich bin mir gerade nicht sicher, ob AutoIt dafür überhaupt geeignet ist, wäre aber schön wenns irgendwie ginge ;)

    Einmal editiert, zuletzt von Scritch (29. August 2011 um 09:40)

  • Dann nutzt doch direkt das Samba-logfile dafür. Dort sollten eigentlich die Namen sowie die Dateien auf die zugegriffen wurde stehen.

    Andy hat mir ein Schnitzel gebacken aber da war ein Raupi drauf und bevor Oscar das Bugfixen konnte kam Alina und gab mir ein AspirinJunkie.

  • Ich habe jetzt eine Alternative gefunden. und zwar die Zugriffszeiten für die nächsten 3 monate zu loggen und wenn ein neuer Zugriff erfolgt ist, diesen zu protkollieren. Die Auswertung wird täglich gemacht. Allerdings stehe ich vor einem Problem mit _Date_Time_GetFileTime. Mein Skript funktioniert teilweise, aber manchmal kommt es vor, dass irgendwie Datenmüll (/2011) in die Auswertungsdatei geschrieben wird. Also, es wird dann, meist wenn man mehrere Dateien auswertet, anstatt des Datums, "/2011" in die Spalte des Datums geschrieben. Das liegt daran, dass bei mir im Skript in dem Array von _Date_Time_GetFileTime nichts steht. Warum ist mir ein Rätsel, da eigentlich was darin stehen sollte.

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <WinAPI.au3>
    #include <Date.au3>
    #include <WindowsConstants.au3>
    #Include <File.au3>
    #include <array.au3>
    #Include <Date.au3>

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

    $datumheute = @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC
    ;~ MsgBox(1, "lala", $datum)

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

    $aDateien = _GetFilesFolder_Rekursiv('.', -1, 0)
    global $aAuswertung
    Global $auswertung = @ScriptDir & "\auswertung.csv"
    if not FileExists($auswertung) Then ;Existiert die Auswertungsdatei noch nicht, dann...
    _filecreate($auswertung) ;Wird sie erstellt...
    dim $aAuswertung[ubound($aDateien)][2] ;Dann wird das Array der Größe des $aDateienarrays angepasst...
    for $c = 1 to ubound($aDateien) - 1 ;und anschliessend die Inhalte von einem Array ins andere übertragen
    $aAuswertung[$c][0] = $aDateien[$c]
    Next
    Else
    _FileReadToArray($auswertung, $aAuswertung) ;muss ein csv2array sein ;Existiert die Datei bereits, wird diese in ein Array aufgenommen. Danach wird weiter unten aufs letzte Zugriffsdatum geprüft, und das Array
    EndIf ;bzw. die Datei mit den neuesten Zugrioffszeiten aktualisiert. Wurde immer nicht auf die Datei in den letzten 16Std. zugegriffen, bleibt
    ;das Datum des letzten Zugriffs bestehen
    fileopen($auswertung, 2)

    for $a = 1 to ubound($aAuswertung) - 1 ;Datei für Datei wird durchgegangen, wann der letzte Zugriffszeitpunkt war

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

    $hFile = _WinAPI_CreateFile($aAuswertung[$a][0], 2)
    $aTime = _Date_Time_GetFileTime($hFile);hier liegt der fehler mit der /2011...
    _WinAPI_CloseHandle($hFile)
    $datumletzterzugriff = _Date_Time_FileTimeToStr($aTime[1]) ;In der Variablen steht, wann das letzte Mal auf die Datei zugegriffen wurde
    if @error Then
    _ArrayDisplay($aTime)
    MsgBox(1, "lala", "lala")
    EndIf
    $letzteUhrzeit = StringRight($datumletzterzugriff, 8) ;Da das letzte Zugriffsdatum + Uhrzeit falsch formatiert von der Funktion zurückgegeben wird, muss das vorher extrahiert werden
    $letzteDatum = @YEAR & "/" & stringleft($datumletzterzugriff, 5)
    $letzterzugriff = $letzteDatum & " " & $letzteuhrzeit

    $dif = _DateDiff("h", $letzteDatum & " " & $letzteuhrzeit, $datumheute)
    if $dif < 2 Then ;Wenn dif = 16 wäre, wäre letzter Zugriff wieder letzte nacht gewesen
    $aAuswertung[$a][1] = $letzterzugriff ;Wurd innerhalb der letzten 16 Stunden auf die Datei zugegriffen, wird das Datum + Uhrzeit ins Array eingetragen
    EndIf
    Next
    for $b = 1 to ubound($aAuswertung) - 1
    FileWrite($auswertung, $aAuswertung[$b][0] & ";" & $aAuswertung[$b][1] & @CRLF) ;Schreibt Array in Datei
    Next
    fileclose($auswertung)

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

    Func _GetFilesFolder_Rekursiv($sPath, $sExt='*', $iDir=-1, $iRetType=0, $sDelim='0')
    Global $oFSO = ObjCreate('Scripting.FileSystemObject')
    Global $strFiles = ''
    Switch $sDelim
    Case '1'
    $sDelim = @CR
    Case '2'
    $sDelim = @LF
    Case '3'
    $sDelim = ';'
    Case '4'
    $sDelim = '|'
    Case Else
    $sDelim = @CRLF
    EndSwitch
    If ($iRetType < 0) Or ($iRetType > 1) Then $iRetType = 0
    If $sExt = -1 Then $sExt = '*'
    If ($iDir < -1) Or ($iDir > 1) Then $iDir = -1
    _ShowSubFolders($oFSO.GetFolder($sPath),$sExt,$iDir,$sDelim)
    If $iRetType = 0 Then
    Local $aOut
    $aOut = StringSplit(StringTrimRight($strFiles, StringLen($sDelim)), $sDelim, 1)
    If $aOut[1] = '' Then
    ReDim $aOut[1]
    $aOut[0] = 0
    EndIf
    Return $aOut
    Else
    Return StringTrimRight($strFiles, StringLen($sDelim))
    EndIf
    EndFunc

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

    Func _ShowSubFolders($Folder, $Ext='*', $Dir=-1, $Delim=@CRLF)
    If Not IsDeclared("strFiles") Then Global $strFiles = ''
    If ($Dir = -1) Or ($Dir = 0) Then
    For $file In $Folder.Files
    If $Ext <> '*' Then
    If StringRight($file.Name, StringLen($Ext)) = $Ext Then _
    $strFiles &= $file.Path & $Delim
    Else
    $strFiles &= $file.Path & $Delim
    EndIf
    Next
    EndIf
    For $Subfolder In $Folder.SubFolders
    If ($Dir = -1) Or ($Dir = 1) Then $strFiles &= $Subfolder.Path & '\' & $Delim
    _ShowSubFolders($Subfolder, $Ext, $Dir, $Delim)
    Next
    EndFunc

    [/autoit]
  • Ich glaub mal das dein Problem daran liegt:

    Gruss DevFly

  • Verbessert mich bitte, falls ich mich irre, aber soweit ich richtig gelesen habe ist hier von einem Linux-Server die Rede.
    AutoIt läuft aber ausschließlich auf Windows.

    MfG, James


  • Stimmt, aber für Linux würde ich dann doch eher auf C umsteigen.

    Dann nutzt doch direkt das Samba-logfile dafür. Dort sollten eigentlich die Namen sowie die Dateien auf die zugegriffen wurde stehen.


    Und diese könnte man dann automatisch jede Woche/jeden Tag mit AutoIt auslesen und verarbeiten.

  • Das war auch erst mein Gedanke, als ich das in der Hilfe gelesen hatte. Stuzig wurde ich dennoch, da das Skript ja teilweise funktioniert. Manche Dateien, die im selben Ordner liegen wie andere, werden fehlerhaft ausgewertet. Und das kann doch nicht sein, dass das Zugriffsdatum für die eine Datei gespeichert wird und für die nächste dann nicht... Das sieht nach reiner Willkühr aus!

    AutoIt läuft aber ausschließlich auf Windows.

    Dessen bin ich mir bewusst. Habe es ja auch nicht versucht unter Linux laufen zu lassen, sondern unter Windows auf eine Samba-Freigabe ;)

    Wine ermöglicht es, Windows-Programme unter anderen Betriebssystemen laufen lassen. Mit Wine kannst Du diese Programme genauso installieren und laufen lassen, wie unter Windows.

    Ist uns leider nicht möglich, Wine einzusetzen!

    Stimmt, aber für Linux würde ich dann doch eher auf C umsteigen.

    Ich möchte für diese eine Auswertung ungern eine komplette Programmiersprache lernen :)

    Und diese könnte man dann automatisch jede Woche/jeden Tag mit AutoIt auslesen und verarbeiten.

    Das wäre das Optimum! Ich habe, wie von chip empfohlen, mal die log.smbd rausgesucht, wo letzte zugriffe drinnenstehen. Allerdings steht da nur folgendes drin:
    [2011/04/26 11:06:35, 0] lib/util_sock.c:get_peer_addr(1224)
    getpeername failed. Error was Der Socket ist nicht verbunden

    Und das gleiche, nur mit anderem Datum, steht über ein paar Tausend Zeilen!

  • Habe mein Problem nun gefunden. Die Funktion gibt auch dann einen Fehler zurück, wenn die Datei schreibgeschützt ist, oder gerade im Zugriff ist. Vll. könnte das ja in die Hilfe mal mit aufgenommen werden ;)

  • Freut mich, wenn du eine Lösung gefunden hast.
    Meine Idee wäre gewesen, anhand der Log-Datei mit SRE eine Whitelist zu erstellen, und dann alle Dateien, die nicht in der Whitelist stehen, zu löschen.

    MfG, James