ubuntuusers.de

Zeitstempel aus gezippter Datei auslesen

Status: Gelöst | Ubuntu-Version: Ubuntu MATE 24.04 (Noble Numbat)
Antworten |

CarstenHa

Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 138

Hallo,

ich benutze z.Z. folgenden Befehl, um den Zeitstempel aus einer Datei auszulesen:

1
gunzip -kN file.txt.gz && stat -c "%w" file.txt

Geht das eigentlich noch besser (ohne die Datei jedes Mal entpacken zu müssen)?

Gruß

Carsten

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13131

CarstenHa schrieb:

ich benutze z.Z. folgenden Befehl, um den Zeitstempel aus einer Datei auszulesen:

1
gunzip -kN file.txt.gz && stat -c "%w" file.txt

Ich glaube nicht, dass das verlässlich funktioniert, weil das "file birth" ist. Das sollte der Zeitpunkt des Auspackens sein. Du willst bestimmt eher den Modifikationszeitpunkt. Und den kann man von der komprimierten Datei ablesen:

1
stat -c '%y' file.txt.gz

CarstenHa

(Themenstarter)
Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 138

rklm schrieb:

Ich glaube nicht, dass das verlässlich funktioniert

Stimmt, du hast recht. Mein Beispiel ist blöd weil "file birth" der Zeitpunkt des Entpackens ist. Die Kernfrage bleibt aber. Wie kann ich bei einer .gz-Datei den "file birth" der gezippten Datei ermitteln, ohne das ich die Datei entpacken muss.

CarstenHa

(Themenstarter)
Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 138

Also ich habe noch ein bisschen getestet. Mein Ubuntu gibt nicht den tatsächlichen Zeitstempel für "file birth" aus. Bei Änderungen an der Datei entspricht der "file birth" der modification time (mit sehr sehr kleinem Zeitunterschied). Mein RaspiOS gibt allerdings den tatsächlichen "file birth" aus. Ich habe jetzt einfach in logrotate-Konfiguration das Komprimieren der entsprechenden Logdateien auf dem Raspi abgestellt. So kann ich den gewünschten Zeitstempel der Log-Datei auslesen. Ich war erst etwas verwirrt über das unterschiedliche Verhalten der verschiedenen Systeme.

Gruß

Carsten

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13131

CarstenHa schrieb:

Stimmt, du hast recht. Mein Beispiel ist blöd weil "file birth" der Zeitpunkt des Entpackens ist. Die Kernfrage bleibt aber. Wie kann ich bei einer .gz-Datei den "file birth" der gezippten Datei ermitteln, ohne das ich die Datei entpacken muss.

Ich hatte gedacht, GZip speichert keine Meta-Daten. Aber diese Python-Doku scheint etwas anderes nahezulegen. Und das wird durch die Definition des Formates bestätigt. Allerdings gibt es "birth" nicht. Soweit ich weiß, kann man "birth" nicht modifizieren (anders als "mtime") und es wird nicht von allen Betriebs- und Dateisystemen unterstützt. Von daher macht es durchaus Sinn, das nicht im Archiv zu speichern. Wenn Du so etwas willst, musst Du einen Archiver verwenden, der das kann. Vielleicht hat GNU tar das drauf - u.U. mit extra Optionen, die Du geben musst. Schau mal auf die Manpage.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13131

CarstenHa schrieb:

Also ich habe noch ein bisschen getestet.

Immer gut.

Mein Ubuntu gibt nicht den tatsächlichen Zeitstempel für "file birth" aus. Bei Änderungen an der Datei entspricht der "file birth" der modification time (mit sehr sehr kleinem Zeitunterschied).

Beachte, dass der Wert von "birth" davon abhängt, wie die Software die Datei ändert - konkret: ob die Datei an der Stelle geändert wird oder eine neue Datei angelegt wird, die dann nachher den Platz der geänderten einnimmt. Du kannst das mit der Inode-Nummer prüfen, wie die jeweilige Software eine Dateiänderung macht.

Ich habe jetzt einfach in logrotate-Konfiguration das Komprimieren der entsprechenden Logdateien auf dem Raspi abgestellt. So kann ich den gewünschten Zeitstempel der Log-Datei auslesen. Ich war erst etwas verwirrt über das unterschiedliche Verhalten der verschiedenen Systeme.

Komprimierung abschalten ist schon ein recht dramatischer Eingriff. Vielleicht erläuterst Du mal, was Du eigentlich erreichen willst. Das ist immer hilfreich, wenn man eine Lösung sucht.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

Also laut RFC1952 ist die MTIME ein Unix-Zeitstempel an Offset 4 in der Datei. Könnte man in Python beispielsweise wie folgt auslesen und anzeigen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env python3
import sys
from datetime import datetime as DateTime

GZIP_MAGIC = b"\x1f\x8b"
GZIP_MTIME_OFFSET = 4
GZIP_MTIME_LENGTH = 4


def main():
    if len(sys.argv) != 2:
        print(f"Usage: {__file__} FILENAME")
        return

    filename = sys.argv[1]
    with open(filename, "rb") as file:
        if file.read(2) != GZIP_MAGIC:
            sys.exit(f"{filename!r} isn't a gzip file")

        if file.seek(GZIP_MTIME_OFFSET) != GZIP_MTIME_OFFSET:
            sys.exit(f"unexpected end of {filename!r}")

        data = file.read(GZIP_MTIME_LENGTH)
        if len(data) != GZIP_MTIME_LENGTH:
            sys.exit(f"unexpected end of {filename!r}")

    print(DateTime.fromtimestamp(int.from_bytes(data, "little")))


if __name__ == "__main__":
    main()

CarstenHa

(Themenstarter)
Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 138

Danke nochmal für Eure Hilfe. Das hat nochmal Licht ins Dunkel gebracht 😉

rklm schrieb:

Vielleicht erläuterst Du mal, was Du eigentlich erreichen willst. Das ist immer hilfreich, wenn man eine Lösung sucht.

Hintergrund ist, das ich mir für meinen Medienserver eine "History"-Skript geschrieben habe. Ich habe die Logstufe des Servers erhöht, lese dann die IDs der zuletzt gestreamten Inhalte aus und kann dann die Datenbank nach weiteren Informationen abfragen. Dank Termux kann ich dann auch die Infos auf dem Smartphone sehen. Die Krux an der Sache war, das trotz höherer Logstufe kein einziger Zeitstempel in den Logdateien zu finden ist. Das wäre ja ein leichtes gewesen das mit den entsprechenden Tools auszulesen (auch gepackt). Und dann habe ich mich ein bisschen "festgebissen" an dem Auslesen des Zeitstempels direkt aus der .gz-Datei. Ich weiß, man könnte auch einen Stempel direkt in die Logdatei schreiben oder die Datei/Ordner überwachen. Aber das funktioniert jetzt so ganz gut mit den ungepackten Logdateien und dem Auslesen des Zeitstempels mit stat.

@Marc_BlackJack_Rintsch

Einen ähnliche Möglichkeit die mtime auszulesen hatte ich auch schon probiert mit dd und perl. Die Python-Lösung finde ich aber genauso spannend. Danke.

Viele Grüße

Carsten

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

Warum dd & Perl wenn man es komplett in Perl machen kann?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/env perl
use strict;
use warnings;
use autodie;

if ($#ARGV == -1) {
    print "Usage: $0 FILENAME\n";
    exit;
}

open my $file, '<:raw', $ARGV[0];
seek $file, 4, 0;
read $file, my $data, 4;
close $file;

print scalar localtime(unpack('V', $data)), "\n";

CarstenHa

(Themenstarter)
Avatar von CarstenHa

Anmeldungsdatum:
1. Mai 2020

Beiträge: 138

Marc_BlackJack_Rintsch schrieb:

Warum dd & Perl wenn man es komplett in Perl machen kann?

Wegen des praktischen Einzeilers:

1
dd if=file.gz count=4 skip=4 bs=1 2>/dev/null | perl -ne 'print scalar localtime(unpack("V", $_)), "\n";'

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13131

CarstenHa schrieb:

Hintergrund ist, das ich mir für meinen Medienserver eine "History"-Skript geschrieben habe.

Also Du brauchst eine Liste von Zeitstempeln samt ID des Inhaltes, der zu diesem Zeitpunkt gestreamt wurde?

Ich habe die Logstufe des Servers erhöht, lese dann die IDs der zuletzt gestreamten Inhalte aus und kann dann die Datenbank nach weiteren Informationen abfragen. [...] Die Krux an der Sache war, das trotz höherer Logstufe kein einziger Zeitstempel in den Logdateien zu finden ist.

Wie sieht denn so eine Logdatei aus?

Das wäre ja ein leichtes gewesen das mit den entsprechenden Tools auszulesen (auch gepackt). Und dann habe ich mich ein bisschen "festgebissen" an dem Auslesen des Zeitstempels direkt aus der .gz-Datei. Ich weiß, man könnte auch einen Stempel direkt in die Logdatei schreiben

Ich dachte das Format ist fix und definiert durch den Medienserver? Du liest doch nur das Log aus, das er sowieso schreibt.

oder die Datei/Ordner überwachen. Aber das funktioniert jetzt so ganz gut mit den ungepackten Logdateien und dem Auslesen des Zeitstempels mit stat.

Naja, bei der Lösung mit dd muss man ja nicht entpacken. Aber wieso reicht die Mod-Time? Das ist nur ein Zeitstempel und ich hätte erwartet, dass in der Logdatei mehrere Einträge sind. Oder schreibt der Server eine Logdatei pro Streamingvorgang?

Antworten |