在Linux(目前使用ext4文件系统)中,如何快速检查文件内容是否被修改没有阅读其中的任何内容?
该stat
命令是推荐的方法吗?我目前做
$ stat --format "%Y" hello.txt
稍后我可以检查相同的命令是否产生相同的输出。如果是这样,我断定 hello.txt 没有改变。
我的感觉是,人们想要输入更多参数才能更加确定。例如,添加文件大小、文件名等是否可以提供更好的文件“指纹”?
关于这个主题,我记得我曾经拥有的 TrueCrypt 卷总是被我的增量备份程序忽略,可能是因为 TrueCrypt 确保不会留下任何元数据更改。我想确实可以更改 所返回的所有数据stat
,因此不能保证获取文件的每个可能的修改?
答案1
如果您想检测文件是否已通过正常方式修改(在某些应用程序中编辑它、从修订控制系统中检出新版本、重建它等),请检查其修改时间 (mtime) 是否已从最后一次检查。这就是stat -c %Y
报道的内容。
修改时间可以通过命令设置touch
。如果要检测文件是否以任何方式发生更改(包括使用touch
、提取存档等),请检查其 inode 更改时间(时间) 与上次检查相比发生了变化。这就是stat -c %Z
报道的内容。除了系统管理员之外,ctime 不能被欺骗(即使如此,也只能通过间接手段:通过更改系统时钟,或绕过文件系统直接访问磁盘)。
答案2
stat 命令的分辨率只有一秒。因此,如果文件在同一秒内被修改两次,您可能会错过修改。 ext4 等较新的文件系统提供了纳秒级更高分辨率的时间戳,但一些旧工具尚未跟上。
此外,其他程序也可以设置任意修改时间。您可以通过 touch 命令了解这是如何发生的。
如果您担心这两种可能性中的任何一种,那么查看文件大小也不是一个坏主意。这就是 rsync 在查找修改后的文件时所做的事情。
答案3
我的感觉是,人们想要输入更多参数才能更加确定。
你所拥有的就是正确的方法。失败的唯一原因是文件系统没有正确更新——在这种情况下,你最终会遇到一大堆更严重的问题。
当然,我假设具有正确知识和对可访问分区的系统的 root 访问权限的人可能能够更改信息以使其成为可能看就好像文件没有被更改一样。然而,在这种情况下,他们肯定会确保对尺寸等做同样的事情。
答案4
我把指纹做得更详细了。
我制作了一个小包装函数,可以为 MacOS/BSD 和 GNU 版本生成相同的输出stat
(还可以检测带有前缀的 Homebrew 安装版本g
)。
init() {
if command -v gstat > /dev/null; then
# GNU coreutils with g prefix.
statCmdArgs=("gstat" "--format=%n %s %b %u %g %i %h %Y %Z %W %o");
elif ! stat --version > /dev/null 2> /dev/null; then
# MacOS/BSD stat
statCmdArgs=("stat" "-f" "%N %z %b %u %g %i %l %m %c %B %k");
else
# Assume GNU version without prefix.
statCmdArgs=("stat" "--format=%n %s %b %u %g %i %h %Y %Z %W %o");
fi;
}
getFileStatus() {
"${statCmdArgs[@]}" "$1";
}
该init
函数在脚本初始化期间被调用一次,并且getFileStatus
可以重复调用而无需检测开销。