Bash脚本 - 判断文件是否被修改?

9
我有一个Bash脚本,每5秒钟会重复复制文件。但通常情况下没有任何更改,这样做有点过度了。
我知道Linux命令`watch`,但由于这个脚本将在OS X计算机上使用(它们没有`watch`,我也不想让每个人都安装macports),我需要能够使用纯Bash代码检查文件是否已修改。
我应该检查文件修改时间吗?如何做到这一点?
编辑:我希望扩展我的脚本,除了复制文件外,如果检测到更改还可以执行其他操作。那么有没有纯Bash的方法来实现这一点呢?

也许你可以使用 rsync 代替?它可以比较源文件和目标文件的时间戳和大小,如果相同则避免复制。(如果你要复制到远程服务器,仍然需要连接的开销。) - Thomas
4个回答

13

如果你需要管理大量文件树,我倾向于同意rsync的答案,但你可以使用-u(--update)标志来执行cp命令,只有在源文件比目标文件新的情况下才会复制文件。

cp -u

编辑

由于你更新了问题并指出了一些额外的操作,你将想要在[ (test)内置命令中使用-nt检查:

#!/bin/bash

if [ $1 -nt $2 ]; then
  echo "File 1 is newer than file 2"
else
  echo "File 1 is older than file 2"
fi

从 man 页面中得知:

file1 -nt file2
         True if file1 is newer (according  to  modification  date)  than
         file2, or if file1 exists and file2 does not.

希望能对你有所帮助。


6

OS X有stat命令。像这样的命令可以给你一个文件的修改时间:

stat -f '%m' filename

GNU 的等效物将是:

stat --printf '%Y\n' filename

3
您可能会发现,通过比较文件大小(如果大小不同,则内容也不同)和内容的哈希值来检测文件内容的更改更可靠。对于此目的,使用哪种哈希算法可能并不重要:SHA1甚至MD5可能已经足够了,您可能会发现cksum命令已经足够。文件修改时间可能会更改而不更改内容(想一想touch file);即使内容发生变化,文件修改时间也可能不会更改(这样做更难,但您可以在编辑文件后使用touch -r ref-file file将文件的修改时间设置为与ref-file匹配)。

为什么要使用哈希而不是逐位比较?难道逐位比较不会比运行整个文件并形成哈希更快吗? - Pacerier
1
@Pacerier:如果文件不同,逐字节比较可能更快,除非最后一个字节是唯一不同的。如果文件相同,您只能通过比较所有字节来显示它。哈希的优点在于可以存储哈希的旧值(相对较小),并将其与从当前文件重新生成的哈希的新值进行比较。如果有差异,则文件已更改。逐字节比较需要存在旧文件。 - Jonathan Leffler

0
不应该使用cp命令来复制文件,而应该使用rsync或其前端之一,因为它会检测文件是否不同,并且只会在它们不同时才复制它们。

5
“rsync”是一个有用的建议(尽管如您在我的编辑中所见,不完全是我需要的)。但我觉得您的语气让人感到有些不舒服。 - Alan H.
1
@Alan H.:也许我有所遗漏,但我并没有觉得这种语气令人反感。事实上,你的回应让我感到惊讶。 - Joshua Nozzi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接