ostatnio otwarty plik

94

Czy można uzyskać czas ostatniego otwarcia pliku i posortować wszystkie pliki w katalogu według tych czasów?

student
źródło

Odpowiedzi:

172

Zależy to dokładnie od tego, co rozumiesz przez „otwarty”, ale ogólnie tak. Zazwyczaj rejestrowane są trzy znaczniki czasu:

  • mtime- aktualizowane po zmianie zawartości pliku. W większości przypadków jest to „domyślny” czas pliku.
  • ctime- aktualizowane po zmianie pliku lub jego metadanych (właściciela, uprawnień)
  • atime - aktualizowane po odczytaniu pliku

Ogólnie rzecz biorąc, chcesz zobaczyć atimeplik. Możesz to uzyskać za pomocą statlub za pomocą ls. Możesz ls -luto zrobić, chociaż wolę używać ls -l --time=atime(który powinien być obsługiwany w prawie wszystkich współczesnych dystrybucjach Linuksa), ponieważ nie używam go często, a kiedy to robię, lepiej go pamiętam. Aby posortować według czasu, dodaj -tflagę do ls. Więc proszę bardzo.

Jest jednak duże zastrzeżenie. Aktualizacja za każdym razem, gdy plik jest odczytywany, powoduje wiele zwykle niepotrzebnych operacji we / wy, spowalniając wszystko. Tak więc większość dystrybucji Linuksa ma teraz domyślnie noatimeopcję montowania systemu plików, która w zasadzie zabija atimes, albo relatimeaktualizuje atime tylko po przekroczeniu limitu (zwykle raz dziennie) lub jeśli plik został faktycznie zmodyfikowany od poprzedniego odczytu. Możesz sprawdzić, czy te opcje są aktywne, uruchamiając mountpolecenie.

Pamiętaj również, że czasy dostępu są podane według i-węzłów, a nie według nazw plików, więc jeśli masz twarde linki, czytanie jednego z nich zaktualizuje wszystkie nazwy odnoszące się do tego samego pliku.

I pamiętaj, że c nie jest „stworzeniem”; tworzenie nie jest śledzone przez systemy plików Unix / Linux, co wydaje się dziwne, ale w rzeczywistości ma sens, ponieważ system plików nie ma możliwości sprawdzenia, czy jest oryginalny - może plik został utworzony czterdzieści lat temu i skopiowany tutaj. W rzeczywistości wiele edytorów plików działa, tworząc kopie na oryginale. Jeśli potrzebujesz tych informacji, najlepiej użyć takiego systemu kontroli wersji git.

mattdm
źródło
9
Dałbym ci więcej niż +1, gdybym mógł, po prostu za to, że nie nazywasz ctime „czasem tworzenia”.
jsbillings
2
Według strony podręcznika mount relatime nie ma nic wspólnego z codziennymi limitami, ale patrzy tylko na atime w stosunku do mtime i ctime. Jeśli atime jest starszy niż mtime lub ctime, atime jest aktualizowany. Jeśli atime jest nowszy niż oba, to pozostawia się go samego. Ma to na celu zachowanie relacji między atime a mtime / ctime, ponieważ niektóre aplikacje używają tych informacji, na przykład mutt, aby sprawdzić, czy przeczytał twoją skrzynkę pocztową od ostatniej aktualizacji.
jw013
1
@ jw013 Tak było od jądra 2.6.30. To prawda, że ​​niektóre starsze dystrybucje mogą nie mieć takiego zachowania. (Ale w przypadku dystrybucji takich jak Fedora było to prawdą nawet wtedy, gdy napisałem oryginalną wersję tej odpowiedzi trzy lata temu.) Poszukaj zaktualizowanej mountstrony podręcznika.
mattdm
1
lsdomyślnie skraca czas do rozsądnej precyzji. Aby dokładnie zobaczyć czas, można użyć --full-time.
jlh
19

ls -ltu wyświetlić listę wszystkich plików, pokazując i sortując według czasu dostępu.

Od 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
źródło
4

findKomenda jest najlepszy do tego. Zobacz -ctime, -mtimeoraz -atimeopcje

GBH
źródło
3

Jeśli twoja lista jest przeznaczona do spożycia przez ludzi, użyj lsz jedną z flag sortowania według daty ( -tudla czasu dostępu (odczytu), tylko -tdla modyfikacji (zapisu) lub -tcczasu zmiany i-węzła). Aby uzyskać więcej informacji, zobacz odpowiedź mattdm (w szczególności zastrzeżenie -ai definicję -c).

Jeśli dotyczy to zużycia programu, analiza wyniku lsjest problematyczna . Jeśli twoją powłoką jest zsh, i tak nie potrzebujesz ls: zsh ma kwalifikatory globowania do sortowania dopasowań poprzez zwiększenie czasu dostępu ( *(Oa)), zmiany i-węzła ( *(Oc)) lub modyfikacji ( *(Om)). Małe litery osortują według wieku.

act_on_files_by_date *(Om)

W przeciwnym razie, jeśli wiesz, że nazwy plików nie zawierają znaków nowej linii ani znaków niedrukowalnych (w bieżącym języku), możesz zrobić coś takiego:

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

Jeśli chcesz wywołać polecenie na wielu plikach jednocześnie, potrzebujesz dodatkowej konfiguracji. Zauważ, że act_on_files_by_date $(ls -t)to nie działa tak samo, ponieważ nazwy plików zawierające znaki wieloznaczne lub białe znaki zostaną rozszerzone w wyniku podstawienia polecenia. Poniższy kod działa, o ile nazwa pliku nie zawiera nowego wiersza ani znaku, który nie może zostać wydrukowany:

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

Jeśli chcesz poradzić sobie z dowolnymi nazwami plików, będziesz miał bardzo trudny czas bez uciekania się do potężniejszych narzędzi niż standardowa powłoka: zsh, perl, python…

Gilles
źródło