última vez que o arquivo foi aberto

94

É possível obter a hora em que o arquivo foi aberto da última vez e classificar todos os arquivos em um diretório nesses horários?

aluna
fonte

Respostas:

172

Isso depende exatamente do que você quer dizer com "aberto", mas, em geral, sim. Existem três carimbos de hora normalmente registrados:

  • mtime- atualizado quando o conteúdo do arquivo é alterado. Este é o horário do arquivo "padrão" na maioria dos casos.
  • ctime- atualizado quando o arquivo ou seus metadados (proprietário, permissões) são alterados
  • atime - atualizado quando o arquivo é lido

Então, geralmente, o que você quer ver é o atimede um arquivo. Você pode conseguir isso com statou com ls. Você pode ls -lufazer isso, embora eu prefira usar ls -l --time=atime(que deve ser suportado em quase todas as distribuições modernas do Linux) porque não o uso com frequência e, quando o faço, me lembro melhor. E para classificar por hora, adicione a -tbandeira a ls. Então lá vai você.

Há uma grande ressalva, no entanto. Atualizar o atime toda vez que um arquivo é lido causa muitas E / S desnecessárias, tornando tudo mais lento. Portanto, a maioria das distribuições Linux agora padroniza a noatimeopção de montagem do sistema de arquivos, que basicamente mata as vezes, ou então relatime, que somente atualiza as vezes quando o limite ultrapassa (normalmente uma vez por dia) ou se o arquivo foi realmente modificado desde a leitura anterior. Você pode descobrir se essas opções estão ativas executando o mountcomando

Além disso, observe que os tempos de acesso são por inode, não por nome de arquivo, portanto, se você tiver hardlinks, a leitura de um atualizará todos os nomes que se referem ao mesmo arquivo.

E lembre-se de que c não é "criação"; a criação não é rastreada pelos sistemas de arquivos Unix / Linux, o que parece estranho, mas faz sentido porque o sistema de arquivos não tem como saber se é o original - talvez o arquivo tenha sido criado há quarenta anos e copiado aqui. E, de fato, muitos editores de arquivos trabalham fazendo cópias sobre o original. Se você precisar dessas informações, é melhor usar um sistema de controle de versão como git.

mattdm
fonte
9
Eu daria a você mais de um, se pudesse, simplesmente por não chamar ctime de "Tempo de Criação".
jsbillings
2
De acordo com a página do manual mount, relatime não tem nada a ver com limites diários, mas só olha para o atime relativo ao mtime e ctime. Se atime for mais antigo que mtime ou ctime, o atime será atualizado. Se atime for mais novo que ambos, será deixado em paz. O objetivo disso é preservar a relação entre atime e mtime / ctime, pois alguns aplicativos usam essas informações, como mutt, para verificar se leu sua caixa de correio desde a última atualização.
jw013
1
@ jw013 Este é o caso desde o kernel 2.6.30. É verdade que algumas distribuições mais antigas podem não ter esse comportamento. (Mas para distribuições como o Fedora, isso era verdade mesmo quando escrevi a versão original desta resposta há três anos.) Procure uma página de mountmanual atualizada .
Mattdm
1
lsreduz o tempo por padrão para uma precisão sensata. Para ver a hora com precisão total, pode-se usar --full-time.
jlh 17/02
19

ls -ltu liste todos os arquivos, mostrando e classificando por hora de acesso.

De 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
fonte
4

O findcomando é melhor para isso. Veja as -ctime, -mtimee -atimeopções

GBH
fonte
3

Se sua listagem for para consumo humano, use lscom um dos sinalizadores de classificação de data ( -tupara hora de acesso (leitura), apenas -tpara hora de modificação (gravação) ou -tcpara hora de alteração do inodo). Veja a resposta de mattdm para obter mais informações (em particular a ressalva -ae a definição de -c).

Se for para consumo do programa, analisar a saída de lsé problemático . Se o seu shell for zsh, você não precisa de lsqualquer maneira: o zsh possui qualificadores de globbing para classificar as correspondências aumentando o tempo de acesso ( *(Oa)), mudança de inode ( *(Oc)) ou modificação ( *(Om)). Uma minúscula oclassifica aumentando a idade.

act_on_files_by_date *(Om)

Caso contrário, se você souber que os nomes dos arquivos não contêm caracteres de nova linha ou não imprimíveis (no código do idioma atual), poderá fazer algo como

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

Se você deseja chamar um comando em muitos arquivos de uma só vez, precisará de mais configurações. Observe que act_on_files_by_date $(ls -t)não funciona assim, pois os nomes de arquivos contendo caracteres curinga ou espaço em branco seriam expandidos no resultado da substituição do comando. O código a seguir funciona desde que nenhum nome de arquivo contenha uma nova linha ou um caractere não imprimível:

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

Se você quiser lidar com nomes de arquivos arbitrários, terá muita dificuldade sem recorrer a ferramentas mais poderosas do que um shell padrão: zsh, perl, python…

Gilles
fonte