在Linux下文件的三种时间标记:访问时间、内容改动时间、状态变化时间

在windows下,一个文件有:创建时间、内容改动时间、访问时间。

而在Linux下,一个文件也有三种时间,分别是:访问时间、内容改动时间、状态变化时间。

两者有些不同,在Linux下没有创建时间的概念,也就是不能知道文件的建立时间,但如果文件建立后就没有修改过,内容改动时间=建立时间;如果文件建立后,状态就没有改动过,那么状态变化时间=建立时间;如果文件建立后,没有被读取过,那么访问时间=建立时间,因为不好判断文件是否被改过、读过、其状态是否变过,所以判断文件的建立时间基本上能为不可能。

如何查看一个文件的三个时间呢?

先用下面的命令来建立一个文件

$ date
2017年 02月 12日 星期日 15:39:25 CST
$ echo "This is the file used to test file time" >filetime.txt
$ ll --full-time filetime.txt
-rw-rw-r--. 1 xiezy xiezy 40 2017-02-12 15:39:37.000000000 +0800 filetime.txt

通过stat filename.txt查看,如:

$ stat filetime.txt
  文件:"filetime.txt"
  大小:40              块:16         IO 块:4096   普通文件
设备:811h/2065d        Inode:197067503   硬链接:1
权限:(0664/-rw-rw-r--)  Uid:( 1000/   xiezy)   Gid:( 1000/   xiezy)
环境:unconfined_u:object_r:user_home_t:s0
最近访问:2017-02-12 15:38:22.000000000 +0800
最近更改:2017-02-12 15:39:37.000000000 +0800
最近改动:2017-02-12 15:39:37.000000000 +0800
创建时间:-

说明:

可以stat *查看这个目录所有文件的状态。

因为这是一个新的文件(filetime.txt),没做过内容、属性的更改,也没读过这个文件,所以三者(访问时间、内容改动时间、状态变化时间)的时间是一致的,这时文件的内容改动时间与这三个时间是一样的,是没有疑问的。

另外除了可以通过stat来查看文件的atime、mtime和ctime外,也可以通过ls命令来查看,具体如下:

ls -lu filename 列出文件的 atime(最后存取时间)
ls -l  filename 列出文件的 mtime(最后内容改动时间)
ls -lc filename 列出文件的 ctime(最后更改时间)

在linux中stat函数中,用st_atime表示文件数据最近的存取时间(last accessed time);用st_mtime表示文件数据最近的内容改动时间(last modified time);使用st_ctime表示文件i节点数据最近的内容改动时间(last i-node's status changed time)。

 字段      说明                           例子            ls( -l)
 st_atime  文件数据的最后读取时间         read            -u
 st_mtime  文件数据的最后内容改动时间     write           缺省
 st_ctime  文件数据的最后状态变化时间     chown,chmod     -c

在linux系统中,系统把文件内容数据与i节点数据是分别存放的,i节点数据存放了文件权限与文件属主之类的数据。

另外,可以格式化输出文件的三种时间,如:

$ find . -name file -printf "%AY-%Am-%Ad %AH:%AM:%AS"
$ find . -name file -printf "%TY-%Tm-%Td %TH:%TM:%TS"
$ find . -name file -printf "%CY-%Cm-%Cd %CH:%CM:%CS"

linux的mtime代表的是文件内容改动时间,如果文件被修改过就很难知道文件的创建时间,在某些特殊情况下,需要查看文件的创建时间,正常情况下查看文件的mtime是无法实现的。可以使用一个变通的方法来实现保留文件创建时间,但是同时也会牺牲一些其它特性。

可以在mount文件的时候使用参数-o noatime,来把系统更新atime的特性关闭。使用了noatime参数挂载后,在文件被修改后文件的atime是不会被改变的,使用stat查看到的atime就是文件的创建时间。如:

# / sbin/mkfs -t ext3 /dev/ram10
# mount -t ext3 -o noatime /dev/loop0 /mnt/foo
# mount
/dev/ram10 on /mnt/foo type ext3 (rw,noatime)
# cd /mnt/foo
# touch filetime1.txt
# stat filetime1.txt 
  File: `filetime1.txt'
  Size: 0               Blocks: 0          IO Block: 4096   Regular File
Device: 10ah/266d       Inode: 12          Links: 1    
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2009-08-04 20:51:32.000000000 +0800
Modify: 2009-08-04 20:51:32.000000000 +0800
Change: 2009-08-04 20:51:32.000000000 +0800
 
# echo foo.ok >> filetime1.txt 
# stat filetime1.txt 
  File: `filetime1.txt'
  Size: 14              Blocks: 2          IO Block: 4096   Regular File
Device: 10ah/266d       Inode: 12          Links: 1    
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2009-08-04 20:51:32.000000000 +0800
Modify: 2009-08-04 20:53:27.000000000 +0800
Change: 2009-08-04 20:53:27.000000000 +0800
 
# cat filetime1.txt 
  foo.ok
# stat filetime1.txt 
  File: `filetime1.txt'
  Size: 14              Blocks: 2          IO Block: 4096   Regular File
Device: 10ah/266d       Inode: 12          Links: 1    
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2009-08-04 20:51:32.000000000 +0800
Modify: 2009-08-04 20:53:27.000000000 +0800
Change: 2009-08-04 20:53:27.000000000 +0800

通过以上实验可以看出文件的access time 是不变的。接着向下多测试一下。

# vi filetime1.txt
# stat filetime1.txt 
  File: `filetime1.txt'
  Size: 23              Blocks: 2          IO Block: 4096   Regular File
Device: 10ah/266d       Inode: 14          Links: 1    
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2009-08-04 20:55:05.000000000 +0800
Modify: 2009-08-04 20:55:05.000000000 +0800
Change: 2009-08-04 20:55:05.000000000 +0800
 
# chmod 777 filetime1.txt 
# stat filetime1.txt 
  File: `filetime1.txt'
  Size: 23              Blocks: 2          IO Block: 4096   Regular File
Device: 10ah/266d       Inode: 14          Links: 1    
Access: (0777/-rwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2009-08-04 20:55:05.000000000 +0800
Modify: 2009-08-04 20:55:05.000000000 +0800
Change: 2009-08-04 20:57:36.000000000 +0800

可见,chmod后,ctime的变化。

另外,从kernel2.6.29开,还默认集成了一个relatime的属性。可能是因为在文件读操作很频繁的系统中,atime更新所带来的开销很大,所以很多SA都在挂装文件系统的时候使用noatime属性来停止更新atime。但是有些程序需要根据atime进行一些判断和操作,所以Linux就推出了一个relatime特性。

使用这个特性来挂装文件系统后,只有当mtime比atime更新的时候,才会更新atime。事实上,这个时候atime和mtime已经是同一个东西了。所以这个选项就是为了实现对atime的兼容才推出的。并不是一个新的时间属性。使用方法就是通过mount -o relatime /dir来挂装目录。

原文出处,有改动。)