在windows系统下查看过文件属性的朋友可能都知道,每个文件都有三个时间参数,分别为:创建时间、修改时间、访问时间。如图:

同样的,linux文件系统下对应每个文件也有三个时间参数,但与windows下略有不同,三个时间分别为:
Access(atime):访问时间,指文件最后一次被访问的时间; Modify(mtime):修改时间,指文件内容最后一次被修改的时间。这里的文件内容指文件内的数据; Change(ctime):状态修改时间,指文件的属性状态一次被修改的时,比如文件权限、所有者、大小等;文件的时间参数对我们是特别重要,尤其是修改时间mtime,比如我们在公司的一个项目组工作,由于一个菜鸟(可能是你)失误改变了一个文件的数据而导致了服务器的奔溃,找出这个文件并复原就是我们必须要做的事情。所以掌握这三个时间的变化规则是我们必要的技能。
atime怎么算访问一个文件呢?比如用cat、more、less指令查看一个文件的内容或用vim编辑器打开一个文件都算一次访问。下面我们研究一下它的变化规则。
测试1:
首先我们创建一个文件,并用stat指令查看文件的inode信息。

用cat指令查看文件内容,并再次查看。我们会发现访问时间atime发生变化。(more、less不再测试,效果相同)

紧接着,我们再次对这个文件进行一次cat操作,时间会不会变化呢?

对比后,你会发现,尽管我们对文件又一次进行了访问,但是访问时间atime并没有发生变化,为什么?系统有bug吗?我们接着进行测试。先注意一下 (此时的修改时间mtime < 访问时间atime)
测试2:
在上面的测试中我并没有往文件内写任何内容。下面我用vim打开文件并写入一个“helloworld”,然后再次stat查看文件的inode信息。(写入过程不再展示)

我们会发现访问时间atime再次“奇迹般”发生了更新变化,而mtime由于改变了文件的数据内容,也发生了更新变化, 此时修改时间mtime=访问时间atime。 (先不管状态修改时间ctime)
紧接着,我们再次用cat查看文件内容,再次stat。

我们会发现,访问时间atime,又发生了更新变化。此时修改时间mtime < 访问时间atime。不要停,实践出真理,我们再一次对该文件进行cat,stat操作。

你发现了什么?访问时间又不变了!! 注意此时mtime< atime。
注意上面加粗字体,我们可以总结出:
当atime > mtime时,我们访问文件,文件访问时间不变。 当atime = mtime时,我们访问文件,文件访问时间更新。Linux文件系统的设计正是这么做的,atime(access time)不更新是有一些历史原因的,在2.6内核以前,我们每次访问文件,atime都会更新。后来OS发现更新atime的开销很大,尤其是读频繁的环境。所以后来mount退出了一个noatime的选项,来禁止更新atime,再后来为了兼容atime,又增加了一个兼容的选项relaime,只有在mtime(modify time)大于等于atime(Access time)时,才会更新access time,后来这也成为了很多系统的默认设置。所以,这个访问时间atime有时候并不靠谱。
mtime当我们修改文件数据内容时,才会更新的时间。
在上面已经测试过,当我们用vim修改文件内容时,文件的修改时间mtime发生更新变化。但因为mtime更新后大于等于atime,并且也vim也打开访问了文件。所以这种变化也引起了atime的更新变化。如上测试2。
是不是所有mtime的变化都会引起atime的变化呢?不是,有时候我们也可以只改变mtime而不改变atime。比如echo指令。
测试3:
使用echo指令,将文件内容修改为“nihao”。此时并没有打开或访问文件内容,所以atime不变(与上图测试2最后一次时间做对比)

ctime
当修改文件状态信息时,才会发生更新变化的时间。关于文件状态信息,stat已经告诉我们了。我们可以主动修改的有size(文件大小),Links(链接数),Access(文件权限),Uid(文件所有者),Gid(文件所属用户组)等。当我们修改这些信息时,文件的ctime都会发生变化。
在上面的一些测试中,我们用vim编辑器修改了文件的内容,导致文件的大小size改变,从而也造成了ctime的更新变化。所以在上面有的测试中ctime会随着mtime变化。
测试4:
改变文件所有者,文件ctime发生更新变化。(与测试3最后一次时间做对比)

改变文件权限,文件ctime发生更新变化。

改变文件链接数,文件ctime发生更新变化。为test.c添加一个硬链接(只有硬链接可以改变文件的链接数Links)

从上面的分析中我们可以知道,文件的三个时间参数的变化是很繁琐的,有时候,我们无意间的一个操作就可能导致文件时间的变化。而当文件时间被误判时,就可能导致程序无法正常运行。所以,如何将一个文件错误的时间修改成正确的时间呢? touch指令可以很好的完成任务!
Touch测试5:
测试基准时间:
touch -a 文件名
将文件的atime,ctime更新到当前时间mtime不变。

touch -c 文件名
当文件不存在时不创建文件;
当文件存在时,将文件的三个时间都更新到当前时间;

或者我们也可以直接touch+文件名也可以达到相同的效果。
touch -d data 文件名当我们不想将文件时间更新为当前日期时,我们可以用data指定一个日期让它进行更新,并且只将atime,mtime更新为指定data。ctime会被更新会当前时间。
例1:

例2:
以当前时间为基准,将atime,mtime更新为两天前,将ctime更新为当前最新时间。

touch -m 文件名
将mtime,ctime修改为当前最新时间,atime不变。

touch -t [YYMMDDhhmm] 文件名 不用当前时间,将指定的时间以 [YYMMDDhhmm] 的格式传入,并且只将atime,mtime更新为指定data。ctime会被更新会当前时间。
