ultimo file aperto


94

È possibile ottenere l'ora in cui il file è stato aperto l'ultima volta e ordinare tutti i file in una directory in quei tempi?

Risposte:


172

Questo dipende esattamente da cosa intendi per "aperto", ma in generale sì. Esistono tre timestamp normalmente registrati:

  • mtime- aggiornato quando cambia il contenuto del file. Questo è il tempo "predefinito" del file nella maggior parte dei casi.
  • ctime- aggiornato quando il file oi suoi metadati (proprietario, autorizzazioni) cambiano
  • atime - aggiornato quando viene letto il file

Quindi, generalmente, quello che vuoi vedere è il atimefile. Puoi ottenerlo con stato con ls. Puoi usarlo ls -luper farlo, anche se preferisco usare ls -l --time=atime(che dovrebbe essere supportato in quasi tutte le moderne distribuzioni Linux) perché non lo uso spesso, e quando lo faccio lo ricordo meglio. E per ordinare in base al tempo, aggiungi la -tbandiera a ls. Quindi eccoti.

C'è un grande avvertimento, però. L'aggiornamento dell'atime ogni volta che viene letto un file provoca un sacco di IO solitamente non necessari, rallentando tutto. Quindi, la maggior parte delle distribuzioni Linux ora sono predefinite noatimeall'opzione mount del filesystem, che in pratica uccide gli atimes, oppure relatimeche aggiorna gli atimes solo quando è passato un limite (normalmente una volta al giorno) o se il file è stato effettivamente modificato dalla lettura precedente. Puoi scoprire se queste opzioni sono attive eseguendo il mountcomando.

Inoltre, si noti che i tempi di accesso sono inode, non per nome file, quindi se si dispone di hardlink, la lettura da uno aggiornerà tutti i nomi che si riferiscono allo stesso file.

E sii consapevole che c non è "creazione"; la creazione non è tracciata dai filesystem Unix / Linux, il che sembra strano ma in realtà ha senso perché il filesystem non ha modo di sapere se è l'originale - forse il file è stato creato quarant'anni fa e copiato qui. E, in effetti, molti editor di file funzionano eseguendo copie sull'originale. Se hai bisogno di tali informazioni, è meglio usare un sistema di controllo della versione come git.


9
Ti darei più di +1 se potessi, semplicemente per non aver chiamato ctime "Tempo di creazione".
jsbillings

2
Secondo la manpage mount, relatime non ha nulla a che fare con i limiti giornalieri, ma guarda solo all'atime relativo a mtime e ctime. Se atime è più vecchio di mtime o ctime, atime viene aggiornato. Se atime è più recente di entrambi, viene lasciato solo. Lo scopo di questo è preservare la relazione tra atime e mtime / ctime, poiché alcune applicazioni usano tali informazioni, come mutt per vedere se ha letto la tua casella di posta dall'ultimo aggiornamento.
jw013,

1
@ jw013 Questo è stato il caso dal kernel 2.6.30. È vero che alcune vecchie distribuzioni potrebbero non avere questo comportamento. (Ma per distribuzioni come Fedora, era vero anche quando ho scritto la versione originale di questa risposta tre anni fa.) Cerca una mountmanpage aggiornata .
Mattdm,

1
lsabbrevia il tempo per impostazione predefinita ad una precisione sensata. Per vedere l'ora con la massima precisione si può usare --full-time.
jlh

19

ls -ltu elenca tutti i file, mostrandoli e ordinandoli in base al tempo di accesso.

Da 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

4

Il findcomando è il migliore per questo. Vedi le -ctime, -mtimee -atimele opzioni


3

Se la tua scheda è destinata al consumo umano, utilizza lsuno dei flag di ordinamento della data ( -tuper l'ora di accesso (lettura), solo -tper l'ora di modifica (scrittura) o -tcper l'ora di cambio dell'inode). Vedi la risposta di mattdm per maggiori informazioni (in particolare le avvertenze riguardanti -ae la definizione di -c).

Se questo è per il consumo del programma, l' analisi dell'output di lsè problematica . Se la tua shell è zsh, non è necessario in lsalcun modo: zsh ha qualificazioni da sballo per ordinare le partite aumentando il tempo di accesso ( *(Oa)), inode change ( *(Oc)) o change ( ) *(Om). Una ospecie minuscola aumentando l'età.

act_on_files_by_date *(Om)

Altrimenti, se sai che i nomi dei file non contengono caratteri di nuova riga o non stampabili (nella locale corrente), puoi fare qualcosa di simile

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

Se si desidera richiamare un comando su più file contemporaneamente, è necessaria una maggiore configurazione. Si noti che act_on_files_by_date $(ls -t)non funziona in questo modo, poiché i nomi di file contenenti caratteri jolly o spazi bianchi verrebbero espansi nel risultato della sostituzione del comando. Il codice seguente funziona purché nessun nome file contenga una nuova riga o un carattere non stampabile:

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

Se vuoi far fronte a nomi di file arbitrari, avrai un momento molto difficile senza ricorrere a strumenti più potenti di una shell standard: zsh, perl, python ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.