您的位置:首页 > 其它

修改文件 访问(access)、修改(modify)、改变(change)时间

2016-09-18 23:07 218 查看
问题:

在写一个文件监测工具,查看文件是否被访问(access)、修改(modify)、改变(change)。 当我在测试的时候发现,测试案例不是很好构建。大家都知道使用
touch
可以修改文件的访问(access)、修改(modify)时间,但是文件的改变(change)时间怎么修改?

1、 访问(access)时间

当我们访问/查看一个文件时, 操作系统会更新文件的访问时间,该时间值可以用
stat
命令查看,如:

#stat -c "%x" test.file
2016-09-18 22:01:10.293904942 +0800

#cat test.file

#stat -c "%x" test.file
2016-09-18 22:02:19.703904944 +0800


我们可以看两次
stat
命令输出的结果不一样。

我们还可以使用
touch
test.file
指定任意访问时间, 如:

#touch -a -d 2001-1-1 0:0:0 test.file
# stat -c "%x" test.file
2001-01-01 00:00:00.000000000 +0800


2、修改(modify)时间

当我们修改一个文件的内容时,文件的修改时间就会改变,如:

#stat -c "%y" test.file
2016-09-18 22:01:10.293904942 +0800
#echo "abc" > test.file
#stat -c "%y" test.file
2016-09-18 22:09:40.523117442 +0800


我们可以看两次
stat
命令输出的结果不一样。

我们还可以使用
touch
test.file
指定任意修改时间, 如:

  #touch -a -d 2001-1-1 0:0:0 test.file
# stat -c "%x" test.file
2001-01-01 00:00:00.000000000 +0800


3、改变(change)时间

最后就是文件的改变时间,这个值比较特殊,它是指文件的元数据(metadata)的修改时间,对应在 linux 中是
inode
,有兴趣可以去看一下具体实现。

现在有一个问题,linux 操作系统没有提供修改 改变时间 的接口/命令,我们该怎么办?

当我们修改文件元数据时,使用当前系统时间作为改变时间的值,没有办法给它赋值。

如果想改变它,只能执行如下操作():

1)将系统时间设置为你想赋值的时间,然后
touch
这个文件;

2)修改内核源码,增加一个用于修改该值的借口;

3)直接访问磁盘,修改该值(如使用 debugfs,注:千万先unmount 的你的磁盘再做)

三种方法,任选其一。

(1)方法一

#!/bin/sh
now=$(date)
echo $now
date --set="Sat May 11 06:00:00 IDT 2013"
touch $1
date --set="$now"


执行上面这个脚本就可以了,如:

./changectime.sh my_filename


方法二:

修改文件:KERNEL_SRC/fs/attr.c

为了简单,我们直接将 修改时间 赋值给 改变时间:

190 int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode)
191 {
...
212         now = current_fs_time(inode->i_sb);
213
214         // attr->ia_ctime = now; //(1) Comment this out
215         if (!(ia_valid & ATTR_ATIME_SET))
216                 attr->ia_atime = now;
217         if (!(ia_valid & ATTR_MTIME_SET))
218                 attr->ia_mtime = now;
else { //mtime is modified to a specific time. (2) Add these lines
attr->ia_ctime = attr->ia_mtime; //Sets the ctime
attr->ia_atime = attr->ia_mtime; //Sets the atime (optional)
}
219         if (ia_valid & ATTR_KILL_PRIV) {
220                 attr->ia_valid &= ~ATTR_KILL_PRIV;
221                 ia_valid &= ~ATTR_KILL_PRIV;
222                 error = security_inode_need_killpriv(dentry);
223                 if (error > 0)
224                         error = security_inode_killpriv(dentry);
225                 if (error)
226                         return error;
227         }
...
279 }


方法三:

这个方法太危险,我暂时没有实际操作过,不做解释。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: