web-dev-qa-db-fra.com

dernière ouverture du fichier

Est-il possible d'obtenir l'heure à laquelle le fichier a été ouvert la dernière fois et de trier tous les fichiers d'un répertoire par ces heures?

101
student

Cela dépend exactement de ce que vous entendez par "ouvert", mais en général, oui. Il y a trois horodatages normalement enregistrés:

  • mtime - mis à jour lorsque le contenu du fichier change. Il s'agit du temps de fichier "par défaut" dans la plupart des cas.
  • ctime - mis à jour lorsque le fichier o ses métadonnées (propriétaire, autorisations) changent
  • atime - mis à jour lors de la lecture du fichier

Donc, généralement, ce que vous voulez voir, c'est le atime d'un fichier. Vous pouvez l'obtenir avec stat ou avec ls. Vous pouvez utiliser ls -lu pour ce faire, même si je préfère utiliser ls -l --time=atime (qui devrait être pris en charge dans presque toutes les distributions Linux modernes) car je ne l'utilise pas souvent, et quand je le fais, je m'en souviens mieux. Et à trier par heure, ajoutez le -t drapeau à ls. Alors voilà.

Il y a cependant une grosse mise en garde. La mise à jour de l'heure à chaque fois qu'un fichier est lu provoque beaucoup d'E/S généralement inutiles, ce qui ralentit tout. Ainsi, la plupart des distributions Linux utilisent désormais par défaut l'option de montage du système de fichiers noatime, qui tue essentiellement atimes, ou bien relatime, qui ne met à jour qu'atimes une fois la limite dépassée (normalement une fois par jour) ou si le fichier a été modifié depuis la lecture précédente. Vous pouvez déterminer si ces options sont actives en exécutant la commande mount.

Notez également que les temps d'accès sont par inode, pas par nom de fichier, donc si vous avez des liens physiques, la lecture à partir de l'un mettra à jour tous les noms qui font référence au même fichier.

Et sachez que c n'est pas "création"; la création n'est pas suivie par les systèmes de fichiers Unix/Linux, ce qui semble étrange mais a du sens car le système de fichiers n'a aucun moyen de savoir s'il s'agit de l'original - le fichier a peut-être été créé il y a quarante ans et copié ici. Et, en fait, de nombreux éditeurs de fichiers fonctionnent en faisant des copies sur l'original. Si vous avez besoin de ces informations, il est préférable d'utiliser un système de contrôle de version comme git.

182
mattdm

ls -ltu liste tous les fichiers, affichant et triant par temps d'accès.

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
21
Shawn J. Goff

La commande find est la meilleure pour cela. Voir le -ctime, -mtime, et -atime options

4
GBH

Si votre fiche est destinée à la consommation humaine, utilisez ls avec l'un des indicateurs de tri de date (-tu Pour l'heure d'accès (lecture), juste -t Pour l'heure de modification (écriture) ou -tc Pour le temps de changement d'inode). Voir réponse de mattdm pour plus d'informations (en particulier l'avertissement concernant -a Et la définition de -c).

Si c'est pour la consommation du programme, l'analyse de la sortie de ls est problématique . Si votre Shell est zsh, vous n'avez pas besoin de ls de toute façon: zsh a des qualificatifs globbing pour trier les correspondances en augmentant l'accès (*(Oa)), le changement d'inode (*(Oc) ) ou de modification (*(Om)). Un o minuscule trie en augmentant l'âge.

act_on_files_by_date *(Om)

Sinon, si vous savez que les noms de fichier ne contiennent aucun caractère de nouvelle ligne ou non imprimable (dans les paramètres régionaux actuels), vous pouvez faire quelque chose comme

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

Si vous souhaitez appeler une commande sur plusieurs fichiers à la fois, vous avez besoin de plus de configuration. Notez que act_on_files_by_date $(ls -t) ne fonctionne pas comme ça, car les noms de fichiers contenant des caractères génériques ou des espaces seraient développés dans le résultat de la substitution de commande. Le code suivant fonctionne tant qu'aucun nom de fichier ne contient une nouvelle ligne ou un caractère non imprimable:

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

Si vous voulez gérer des noms de fichiers arbitraires, vous aurez beaucoup de mal à recourir à des outils plus puissants qu'un shell standard: zsh, Perl, python…