Every wondered what the timestamps on files on UNIX sytems mean?

Unix keeps three or four timestamps per file (or directory (or other random thing in the file system).

The default timestamp is mtime. mtime is the modification time, the last time the file was written to. It’s the time that is displayed by ls -l.

Next is the somewhat confusing ctime. People often mistake the c as standing for create, but it actually stands for change. ctime is the last time the directory entry, the files inode, changed. This happens when the file is written to, but also when the ownership is changed with chown or chgrp, when the permission are change with chmod, the file is renamed with mv, or linked to with ln. The result of all this is that it’s always the case that ctime >= mtime.

ctime can be view with ls -lc.

Last and least, is atime. atime is the access time, the time the file was last read. For directories being “read” means anything that cds to a directory or lists files in it. This isn’t always obvious, for example git status will update the ctime of all of the directories in the repo (that aren’t ignored) as it scans for changed files.

Updating atime is often turned off to reduce disk writes (a write is needed every time a file is read). When atime is not being updated by reads, it’s usually set to the value of mtime.

atime is viewed with ls -lu

Notice none of those timestamps tell you when the file was created. Some filesystems have a fourth stamp birthtime or crtime which is the time the file was created. It’s easy to see on OS X (HSF filesystem) or FreeBSD (UFS2,ZFS) by adding the -U option to ls. Given a file that was create in May and updated in June:

ls -l foo.txt
-rw-r--r--  1 spike  staff  2452 Jun 16 18:40 foo.txt
ls -lU foo.txt
-rw-r--r--  1 spike  staff  2452 May 15 09:04 foo.txt

On Linux systems, ls does not have an option to display the creation time. You can view it with stat.

stat foo.txt
 File: ‘foo.txt’
  Size: 528           Blocks: 8          IO Block: 4096   regular file
Device: ca07h/51719d  Inode: 16          Links: 1
Access: (0600/-rw-------)  Uid: (  108/   spike)   Gid: (  108/   spike)
Access: 2015-06-17 10:06:40.197949999 -0600
Modify: 2015-06-16 18:41:08.061949999 -0600
Change: 2015-06-16 18:41:08.061949999 -0600
 Birth: -

Note that “Birth” blank. This output is from the ext4 filesytem, which supposedly does track creation, but doesn’t provide it in a way stat wants to see it. You’re mileage may vary, but I’ve yet to find a Linux file system the provides easy access to file creation time. If you know of one, share it in the comments.

Hopefully, this eliminates some of the confusion surrounding what Unix timestamps mean. In the not too distant future, I’ll put this to practically use with find.