134

I want to find out the creation date of a particular file on a Linux system. Not the modification date or access date, the creation date.

I have tried with ls -ltrh and stat filename but neither gives me what I need. What else can I do to get this information?

4
  • 11
    Linux doesn't keep track of the creation time since it is not required by POSIX. However, Mac OS X does with the HFS filesystem — look under "birth time" in stat(1). Commented Sep 18, 2013 at 5:15
  • 3
    Fedora 19 ext4 filesystems do set file creation times. I'm sure there are many more examples. See answer below that uses stap to retrieve creation times.
    – rickhg12hs
    Commented Oct 15, 2013 at 13:11
  • 3
    see unix.stackexchange.com/questions/7562/…
    – jlliagre
    Commented Feb 25, 2014 at 19:08
  • @200_success: stat still works on the MacOS' APFS; e.g. stat -f "%m%t%SB %N" ./myfile.txt | cut -f2-
    – Seamus
    Commented May 11, 2021 at 23:50

8 Answers 8

121

stat -c '%w' file on filesystems that store creation time.

Note that on Linux this requires coreutils 8.31, glibc 2.28 and kernel version 4.11 or newer.

The POSIX standard only defines three distinct timestamps to be stored for each file: the time of last data access, the time of last data modification, and the time the file status last changed.

Modern Linux filesystems, such as ext4, Btrfs, XFS (v5 and later) and JFS, do store the file creation time (aka birth time), but use different names for the field in question (crtime in ext4/XFS, otime in Btrfs and JFS). Linux provides the statx(2) system call interface for retrieving the file birth time for filesystems that support it since kernel version 4.11. (So even when creation time support has been added to a filesystem, some deployed kernels have not immediately supported it, even after adding nominal support for that filesystem version, e.g., XFS v5.)

As Craig Sanders and Mohsen Pahlevanzadeh pointed out, stat does support the %w and %W format specifiers for displaying the file birth time (in human readable format and in seconds since Epoch respectively) prior to coreutils version 8.31. However, coreutils stat uses the statx() system call where available to retrieve the birth time only since version 8.31. Prior to coreutils version 8.31 stat accessed the birth time via the get_stat_birthtime() provided by gnulib (in lib/stat-time.h), which gets the birth time from the st_birthtime and st_birthtimensec fields of the stat structure returned by the stat() system call. While for instance BSD systems (and in extension OS X) provide st_birthtime via stat, Linux does not. This is why stat -c '%w' file outputs - (indicating an unknown creation time) on Linux prior to coreutils 8.31 even for filesystems which do store the creation time internally.

As Stephane Chazelas points out, some filesystems, such as ntfs-3g, expose the file creation times via extended file attributes.

2
  • 1
    You can use stap to create your own kernel API. See example in answer here.
    – rickhg12hs
    Commented Oct 15, 2013 at 13:12
  • POSIX is actually wrong on this. mtime used to be both mtime and ctime, and ctime was creation time in orginal unix. see blog.plover.com/Unix/ctime.html
    – Dani_l
    Commented Jul 31, 2020 at 14:14
30

TLDR; Use stap ("SystemTap") to create your own kernel API. Demo of ext4 creation time extraction below.

You can extract the ext4 creation times on Fedora 19 systems. Here's mine:

$ uname -a
Linux steelers.net 3.11.1-200.fc19.i686.PAE #1 SMP Sat Sep 14 15:20:42 UTC 2013 i686 i686 i386 GNU/Linux

It's clear that the inodes on my ext4 partitions have the creation time. Here's a shell script that determines the inode associated with a filename and then augments the stat output with the creation time by using stap ("systemtap").

NB: This is just a demo and hugely inefficient since a kernel module is created, loaded, and unloaded for every execution. This is also probably very fragile as no error checking is performed. A proper kernel API would be preferable, but this script could be made much more efficient and read the creation times of multiple files/inodes.

[contents of stap_stat.sh]

#/bin/sh

my_inode_str=$(stat --printf="%i" $1)

stap - << end_of_stap_script
global my_offsetof
probe begin {
  system("stat $1");
  my_offsetof = &@cast(0,"struct ext4_inode_info")->vfs_inode;
}
probe kernel.function("ext4_getattr@fs/ext4/inode.c") {
  probe_inode=\$dentry->d_inode;
  if (@cast(probe_inode, "struct inode")->i_ino == $my_inode_str) {
    my_i_crtime = &@cast(probe_inode - my_offsetof,"struct ext4_inode_info")->i_crtime;
    printf("CrTime: %s GMT\n", ctime(@cast(my_i_crtime, "timespec")->tv_sec));
    printf("CrTime (nsecs): %d\n", @cast(my_i_crtime, "timespec")->tv_nsec);
    exit();
  }
}
end_of_stap_script

Here's a demo:

$ ll testfile
ls: cannot access testfile: No such file or directory
$ touch testfile
$ ./stap_stat.sh testfile
  File: ‘testfile’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:17:04.221441084 -0400
Modify: 2013-09-28 06:17:04.221441084 -0400
Change: 2013-09-28 06:17:04.221441084 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ ll testfile
-rw-rw-r--. 1 Rick Rick 0 Sep 28 06:17 testfile
$ cat - >> testfile 
Now is the time ...
$ ll testfile 
-rw-rw-r--. 1 Rick Rick 20 Sep 28 06:18 testfile
$ ./stap_stat.sh testfile
  File: ‘testfile’
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:17:04.221441084 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:18:33.684374740 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ cat testfile 
Now is the time ...
$ ./stap_stat.sh testfile
  File: ‘testfile’
  Size: 20          Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:19:12.199349463 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:18:33.684374740 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ mv testfile testfile2
$ ./stap_stat.sh testfile2 
  File: ‘testfile2’
  Size: 20          Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 4850501     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/    Rick)   Gid: ( 1001/    Rick)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2013-09-28 06:19:12.199349463 -0400
Modify: 2013-09-28 06:18:33.684374740 -0400
Change: 2013-09-28 06:20:45.870295668 -0400
 Birth: -
CrTime: Sat Sep 28 10:17:04 2013 GMT
CrTime (nsecs): 220441085
$ 
2
  • 8
    Ok, that is just cool. +1 for using stap, monkey patching the linux kernel, awesome. Commented Jun 24, 2015 at 1:20
  • 1
    @ChrisMagnuson: debugfs + stat allow to get crtime without monkey patching the kernel.
    – jfs
    Commented Jul 26, 2016 at 13:41
22

In theory, with GNU stat you could use stat -c '%w' or %W to get a file's creation date (aka birthtime).

In practice, most filesystems do not record that information and the linux kernel does not provide any way of accessing it.

The closest you can get is the file's ctime, which is not the creation time, it is the time that the file's metadata was last changed.

Linux Weekly News had an interesting article about this a few years back - File creation times.

1
  • Update: Since Linux 4.11, it is actually possible to retrieve crtime (on filesystems that support it). Commented Jan 20, 2022 at 8:15
20

In ext4 it is possible; because ext4 file-system stores the file creation time. But still, you will find that the stat command is unable to show the date, because I think the kernel is not having any APIs for this.

Anyway, the file birth time is stored in ext4 and you can find it out, although not by a direct method, but by using debugfs

sudo debugfs -R "stat /ABSOLUTE/PATH" /dev/sdxX | grep crtime

2
  • 1
    as a bash function: xstat filename
    – jfs
    Commented Jul 26, 2016 at 13:39
  • 1
    If /dev/sdxX is mounted in /some/path and the file is /some/path/some/file, the path to be specified is only some/file: its path must be referred not to the filesystem root, but to the mountpoint. Otherwise, the file won't be found.
    – BowPark
    Commented Jun 27, 2018 at 13:33
12

In OS X you can use ls -lU, stat -f%B, GetFileInfo -d, or mdls -n kMDItemFSCreationDate:

$ ls -lU
total 0
-rw-r--r--  1 lauri  staff  0 Apr 25 03:58 a
$ stat -f%B a
1398387538
$ stat -f%SB -t %Y%m%d%H%M a
201404250358
$ GetFileInfo -d a
04/25/2014 03:58:58
$ mdls -n kMDItemFSCreationDate a
kMDItemFSCreationDate = 2014-04-25 00:58:58 +0000
1
  • 1
    Very useful, thanks! Evidently there's more than one way to do it.
    – GDP2
    Commented Feb 17, 2020 at 17:52
9
stat --printf='%w' yourfile   #human readable

stat --printf='%W' yourfile   #seconds from Epoch , 0 if unknown

Difference between FreeBSD and GNU\Linux on stat command:

If you call stat command in GNU\Linux it invokes the -x option, but in FreeBSD, you yourself should invoke the -x option.

See also What file systems on Linux store the creation time?

Notes: --printf is very useful in scripting....!

2
  • // , Tried this on a CEntOS 6 machine, and all I got were question marks: $ stat --printf='%w' ~/dump.rdb ? Maybe my file system doesn't support stat with %w. Commented Aug 21, 2015 at 19:23
  • unfortunately, HFS doesn't support ctime. Commented Aug 22, 2015 at 9:33
3

Check this out:

# the last arg is the device to scan in.
debugfs -R 'stat /home/renich/somefile' /dev/sda1

BTW, this works on ext4 only. I haven't found a solution for BtrFS... yet ;)

2
  • 1
    That's pretty much what beginer's answer says... isn't it ? Commented Dec 28, 2015 at 23:49
  • whoops, you're right @don_crissti
    – Renich
    Commented Dec 30, 2015 at 0:49
0

I am using ubuntu, and most files are under ext4 file system, so we can ignore cases in other ones, like Btrfs, XFS (v5 and later) and JFS.

The standard ext4 Linux file system allocates space for a file-creation timestamp in its internal file system structures, but this hasn’t been implemented yet (I tried on Ubuntu 20.04)

Use this as an alternative:

stat --format='%z' {{YOUR_file}} 

%z: time of last status change, human-readable. (aka ctime)
ctime: Changed timestamps, aren’t referring to changes made to the contents of a file. Rather, it’s the time at which the metadata related to the file was changed. File permission changes, for example, will update the changed timestamp.

atime v.s ctime v.s. mtime:
https://www.howtogeek.com/517098/linux-file-timestamps-explained-atime-mtime-and-ctime/

more about metadate of a file:
https://www.cs.columbia.edu/~smb/classes/s06-4118/l21.pdf

1
  • 1
    It has been implemented. Use 20.10 or newer and stat should work OOTB for showing creation time on ext4.
    – muru
    Commented Nov 13, 2021 at 3:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .