Zuletzt geöffnete Datei

94

Ist es möglich, die Uhrzeit zu ermitteln, zu der die Datei zuletzt geöffnet wurde, und alle Dateien in einem Verzeichnis nach dieser Uhrzeit zu sortieren?

Student
quelle

Antworten:

172

Dies hängt genau davon ab, was Sie mit "geöffnet" meinen, aber im Allgemeinen ja. Normalerweise werden drei Zeitstempel aufgezeichnet:

  • mtime- aktualisiert, wenn sich der Inhalt der Datei ändert. Dies ist in den meisten Fällen die "Standard" -Dateizeit.
  • ctime- aktualisiert, wenn sich die Datei oder ihre Metadaten (Eigentümer, Berechtigungen) ändern
  • atime - aktualisiert, wenn die Datei gelesen wird

Im Allgemeinen ist das, was Sie sehen möchten, das atimeeiner Datei. Das kann man mit statoder mit bekommen ls. Sie können ls -ludies tun, obwohl ich es vorziehen würde ls -l --time=atime(was in fast allen modernen Linux-Distributionen unterstützt werden sollte), weil ich es nicht oft benutze und wenn ich es tue, kann ich mich besser daran erinnern. Und um nach Zeit zu sortieren , fügen Sie das -tFlag zu ls hinzu. Hier bitteschön.

Es gibt jedoch eine große Einschränkung. Das Aktualisieren der Zeit jedes Mal, wenn eine Datei gelesen wird, verursacht eine Menge normalerweise unnötiger E / A und verlangsamt alles. Daher verwenden die meisten Linux-Distributionen standardmäßig die noatimeMount-Option für das Dateisystem, die im Grunde genommen manchmal nicht funktioniert, oder relatimedie nur dann aktualisiert wird, wenn ein Limit überschritten wurde (normalerweise einmal pro Tag) oder wenn die Datei seit dem letzten Lesevorgang tatsächlich geändert wurde. Sie können feststellen, ob diese Optionen aktiv sind, indem Sie den mountBefehl ausführen.

Beachten Sie auch, dass die Zugriffszeiten nach Inode und nicht nach Dateiname angegeben werden. Wenn Sie also über Hardlinks verfügen, werden beim Lesen von 1 alle Namen aktualisiert, die auf dieselbe Datei verweisen.

Und sei dir bewusst, dass c nicht "Schöpfung" ist; Die Erstellung wird nicht von Unix / Linux-Dateisystemen verfolgt, was seltsam erscheint, aber tatsächlich sinnvoll ist, da das Dateisystem nicht weiß, ob es sich um das Original handelt - möglicherweise wurde die Datei vor vierzig Jahren erstellt und hierher kopiert. Tatsächlich arbeiten viele Datei-Editoren damit, Kopien über das Original zu erstellen. Wenn Sie diese Informationen benötigen, verwenden Sie am besten ein Versionskontrollsystem wie git.

mattdm
quelle
9
Ich würde dir mehr als +1 geben, wenn ich könnte, einfach weil ich ctime nicht "Creation Time" nenne.
Jsbillings
2
Laut der Mount-Manpage hat relatime nichts mit Tageslimits zu tun, sondern betrachtet nur die Zeit relativ zu mtime und ctime. Wenn atime älter als mtime oder ctime ist, wird atime aktualisiert. Wenn atime neuer als beide ist, wird es in Ruhe gelassen. Dies dient dazu, die Beziehung zwischen atime und mtime / ctime beizubehalten, da einige Anwendungen diese Informationen verwenden, z. B. mutt, um festzustellen, ob Ihr Postfach seit der letzten Aktualisierung gelesen wurde.
jw013
1
@ jw013 Dies ist seit dem Kernel 2.6.30 der Fall. Es ist richtig, dass einige ältere Distributionen dieses Verhalten möglicherweise nicht aufweisen. (Aber für Distributionen wie Fedora stimmte das schon, als ich vor drei Jahren die Originalversion dieser Antwort schrieb.) Suchen Sie nach einer aktualisierten mountManpage.
Mattdm
1
lsverkürzt die Zeit standardmäßig auf eine vernünftige Genauigkeit. Um die Zeit in voller Präzision zu sehen, kann man verwenden --full-time.
17.
19

ls -ltu liste alle dateien auf, zeige und sortiere nach zugriffszeit.

Von man ls:

-u     with -lt: sort by, and show, access time with -l: show access
       time and sort by name otherwise: sort by access time
Shawn J. Goff
quelle
4

Der findBefehl ist dafür am besten geeignet. Siehe die -ctime, -mtimeund -atimeOptionen

GBH
quelle
3

Wenn Ihr Eintrag für den menschlichen Verzehr bestimmt ist, verwenden Sie ihn lsmit einem der Datumssortierungsflags ( -tufür die Zugriffszeit (Lesezeit), nur -tfür die Änderungszeit (Schreibzeit) oder -tcfür die Inode-Änderungszeit). Siehe mattdm Antwort für weitere Informationen (insbesondere in Bezug auf die Einschränkung -aund die Definition -c).

Wenn dies für den Programmverbrauch vorgesehen ist, ist das Parsen der Ausgabe von lsproblematisch . Wenn Ihre Shell zsh ist, brauchen Sie das auch nicht ls: zsh hat Globbing-Qualifikatoren, um die Übereinstimmungen zu sortieren, indem Sie die Zugriffszeit ( *(Oa)), die Inode-Änderung ( *(Oc)) oder die Änderungszeit ( *(Om)) erhöhen . Ein Kleinbuchstabe osortiert nach zunehmendem Alter.

act_on_files_by_date *(Om)

Wenn Sie sonst wissen, dass die Dateinamen keine Zeilenumbrüche oder nicht druckbaren Zeichen enthalten (im aktuellen Gebietsschema), können Sie so etwas tun

ls -t | while read -r name; do act_on_one_file "$name"; done
ls -t | xargs -I {} act_on_one_file {}

Wenn Sie einen Befehl für viele Dateien gleichzeitig aufrufen möchten, müssen Sie weitere Einstellungen vornehmen. Beachten Sie, dass act_on_files_by_date $(ls -t)dies nicht so funktioniert, da Dateinamen, die Platzhalterzeichen oder Leerzeichen enthalten, im Ergebnis der Befehlsersetzung erweitert werden. Der folgende Code funktioniert, solange kein Dateiname eine neue Zeile oder ein nicht druckbares Zeichen enthält:

IFS='
'
set -f
act_on_files_by_date $(ls -t)
set +f
unset IFS

Wenn Sie mit willkürlichen Dateinamen fertig werden möchten, haben Sie es sehr schwer, ohne auf leistungsfähigere Werkzeuge als eine Standard-Shell zurückzugreifen: zsh, perl, python ...

Gilles
quelle