Comment trouver l'heure de création d'un fichier?

55

Je dois trouver l'heure de création d'un fichier. Lorsque j'ai lu certains articles sur ce problème, ils ont tous indiqué qu'il n'y avait pas de solution (comme Site1 , Site2 ).

Lorsque j'ai essayé la commande stat , elle indique Birth: - .

Alors, comment puis-je trouver l'heure de création d'un fichier?

    
posée nux 21.05.2014 - 16:16
la source

4 réponses

58

Il existe un moyen de connaître la date de création d'un répertoire, procédez comme suit:

  1. Connaissez l'inode du répertoire à l'aide de la commande ls -i (disons, par exemple, son X )

  2. Sachez sur quelle partition votre répertoire est sauvegardé par la commande df -T /path (disons que c'est sur /dev/sda1 )

  3. Maintenant, utilisez cette commande: sudo debugfs -R 'stat <X>' /dev/sda1

Vous verrez dans la sortie:

crtime: 0x4e81cacc:966104fc -- mon Sep 27 14:38:28 2013

crtime correspond à la date de création de votre fichier.

Ce que j'ai testé :

  1. Création d'un répertoire à une heure spécifique.
  2. y a accédé.
  3. Modifiez-le en créant un fichier.

  4. J'ai essayé la commande et elle a donné l'heure exacte.

  5. Ensuite, je le modifie et teste à nouveau, le crtime est resté le même, mais les modifications et les accès ont changé.
réponse donnée nux 21.05.2014 - 16:16
la source
51

@Nux a trouvé une excellente solution pour laquelle vous devriez tous avoir un vote positif. J'ai décidé d'écrire une petite fonction qui peut être utilisée pour tout exécuter directement. Ajoutez simplement ceci à votre ~/.bashrc .

get_crtime() {

    for target in "${@}"; do
        inode=$(stat -c '%i' "${target}")
        fs=$(df  --output=source "${target}"  | tail -1)
        crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null | 
        grep -oP 'crtime.*--\s*\K.*')
        printf "%s\t%s\n" "${target}" "${crtime}"
    done
}

Maintenant, vous pouvez exécuter get_crtime pour imprimer les dates de création de autant de fichiers ou de répertoires que vous le souhaitez:

$ get_crtime foo foo/file 
foo Wed May 21 17:11:08 2014
foo/file    Wed May 21 17:11:27 2014
    
réponse donnée terdon 21.05.2014 - 17:29
la source
6

L'incapacité de stat d'afficher l'heure de création est due à la limitation du stat(2) appel système , dont la structure de retour n'incluait pas de champ pour l'heure de création. À partir de Linux 4.11 (c’est-à-dire 17.10 et plus récent *), New statx(2) L’appel système est disponible, ce qui inclut une heure de création dans sa structure de retour.

* Et éventuellement sur les versions antérieures de LTS utilisant les noyaux de pile d’activation matérielle (HWE). Vérifiez uname -r pour vérifier si vous utilisez un noyau au moins à 4.11 pour confirmer.

Malheureusement, il n'est pas facile d'appeler des appels système directement dans un programme C. Glibc fournit généralement un wrapper qui facilite la tâche, mais elle n’a ajouté un wrapper que pour statx(2) en août 2018 (version 2.28 , disponible en 18.10). Heureusement, @whotwagner a écrit un exemple de programme C qui montre comment utiliser l'appel système statx(2) sur x86 et x86-64. systèmes. Sa sortie est au même format que celle par défaut de stat , sans aucune option de formatage, mais il est simple de le modifier pour n’imprimer que l’heure de naissance.

D'abord, clonez-le:

git clone https://github.com/whotwagner/statx-fun

Vous pouvez compiler le code statx.c ou, si vous voulez seulement l'heure de naissance, créer un birth.c dans le répertoire cloné avec le code suivant (qui est une version minimale de statx.c n'imprimant que l'horodatage de la création précision nanoseconde comprise):

#define _GNU_SOURCE
#define _ATFILE_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include "statx.h"
#include <time.h>
#include <getopt.h>
#include <string.h>

// does not (yet) provide a wrapper for the statx() system call
#include <sys/syscall.h>

/* this code works ony with x86 and x86_64 */
#if __x86_64__
#define __NR_statx 332
#else
#define __NR_statx 383
#endif

#define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))

int main(int argc, char *argv[])
{
    int dirfd = AT_FDCWD;
    int flags = AT_SYMLINK_NOFOLLOW;
    unsigned int mask = STATX_ALL;
    struct statx stxbuf;
    long ret = 0;

    int opt = 0;

    while(( opt = getopt(argc, argv, "alfd")) != -1)
    {
        switch(opt) {
            case 'a':
                flags |= AT_NO_AUTOMOUNT;
                break;
            case 'l':
                flags &= ~AT_SYMLINK_NOFOLLOW;
                break;
            case 'f':
                flags &= ~AT_STATX_SYNC_TYPE;
                flags |= AT_STATX_FORCE_SYNC;
                break;
            case 'd':
                flags &= ~AT_STATX_SYNC_TYPE;
                flags |= AT_STATX_DONT_SYNC;
                break;
            default:
                exit(EXIT_SUCCESS);
                break;
        }
    }

    if (optind >= argc) {
        exit(EXIT_FAILURE);
    }

    for (; optind < argc; optind++) {
        memset(&stxbuf, 0xbf, sizeof(stxbuf));
        ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
        if( ret < 0)
        {
            perror("statx");
            return EXIT_FAILURE;
        }
        printf("%lld.%u\n", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);
    }
    return EXIT_SUCCESS;
}

Ensuite:

$ make birth
$ ./birth ./birth.c
1511793291.254337149
$ ./birth ./birth.c | xargs -I {} date -d @{}
Mon Nov 27 14:34:51 UTC 2017

En théorie, cela devrait rendre le temps de création plus accessible:

  • davantage de systèmes de fichiers supportés que les systèmes ext * ( debugfs est un outil pour les systèmes de fichiers ext2 / 3/4 et inutilisable pour les autres)
  • vous n'avez pas besoin de root pour l'utiliser (à l'exception de l'installation de certains paquetages requis, tels que make et linux-libc-dev ).

Tester un système xfs, par exemple:

$ truncate -s 1G temp; mkfs -t xfs temp; mkdir foo; sudo mount temp foo; sudo chown $USER foo
$ touch foo/bar
$ # some time later
$ echo > foo/bar
$ chmod og-w foo/bar
$ ./birth foo/bar | xargs -I {} date -d @{}
Mon Nov 27 14:43:21 UTC 2017
$ stat foo/bar                             
  File: foo/bar
  Size: 1           Blocks: 8          IO Block: 4096   regular file
Device: 700h/1792d  Inode: 99          Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/ muru)      Gid: ( 1000/ muru)
Access: 2017-11-27 14:43:32.845579010 +0000
Modify: 2017-11-27 14:44:38.809696644 +0000
Change: 2017-11-27 14:44:45.536112317 +0000
 Birth: -

Cependant, cela n'a pas fonctionné pour NTFS et exfat. Je suppose que les systèmes de fichiers FUSE pour ceux-ci n'incluaient pas le moment de la création.

Si, ou plutôt quand, glibc ajoute le support pour l'appel système statx(2) , stat suivra bientôt et nous pourrons utiliser l'ancienne commande stat . Mais je ne pense pas que cela sera reporté dans les versions LTS, même s’ils obtiennent de nouveaux noyaux. Donc, je ne m'attends pas à ce que stat sur les versions actuelles de LTS (14.04, 16.04 ou 18.04) imprime jamais l'heure de création sans intervention manuelle.

Cependant, le 18.10, vous pouvez directement utiliser la fonction statx comme décrit dans man 2 statx (notez que la page de manuel 18.10 indique incorrectement que glibc n'a pas encore ajouté le wrapper).

    
réponse donnée muru 27.11.2017 - 15:52
la source
3

TL; DR: Il suffit de courir: sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>

(Pour connaître votre fs, exécutez df -T /path/to/your/file , il s'agira probablement de /dev/sda1 ).

Version longue:

Nous allons exécuter deux commandes:

  1. Recherchez le nom du nom de la partition pour votre fichier.

    df -T /path/to/your/file
    

    La sortie ressemblera à ceci (le nom de la partition est le premier):

    Filesystem     Type 1K-blocks    Used Available Use% Mounted on
    /dev/<your fs> ext4   7251432 3481272   3509836  50% /
    
  2. Découvrez l'heure de création de ce fichier.

    sudo debugfs -R 'stat /path/to/your/file' /dev/<your fs>
    

    Dans la sortie, recherchez ctime .

réponse donnée Lukasz Czerwinski 14.01.2016 - 21:19
la source

Lire d'autres questions sur les étiquettes